Twilio无法播放AWS S3中Chrome录制音频的问题排查
问题:TwiML 播放S3存储的Chrome录制音频报错12300
将Chrome录制的音频上传到AWS S3后,使用TwiML <Play>动词播放时触发错误码12300(无法获取Play URL),示例URL为https://xxxx.s3.amazonaws.com/recordings/dev/prompt-26-87.mp3,文件的Content-Type始终为video/webm。
文件可在浏览器正常播放,说明URL和上传流程无问题,但怀疑Content-Type或音频格式本身不被<Play>支持。
前端Ajax上传代码
this.uploadAudio = function(fname) { if(self.audioBlobs[fname]) { let url = $('#upload-recording-url').val(); let fd = new FormData(); fd.append('fname', fname); fd.append('data', self.audioBlobs[fname]); $.ajax({ type: 'POST', url: url, data: fd, processData: false, contentType: 'audio/mpeg' }).done(function(data) { }); } }
PHP后端(Flysystem上传到S3)代码
public function uploadRecording(Request $request, LoggerInterface $callcenterLogger ): Response { try { $fname = $request->request->get('fname'); $data = $request->files->get('data'); $tempFile = $_FILES['data']['tmp_name']; $blob = file_get_contents($tempFile); $repo = $this->getFileRepositories()->getFileRepo('recordings'); $root = $repo->getAbsoluteWebRoot(); $env = $_ENV['APP_ENV']; $path = $env.'/'.$fname; $repoName = $repo->write($path, $blob); return new JsonResponse(['success' => true, 'repo_name' => $repoName]); } catch(\Exception $ex) { return new JsonResponse(['success' => false, 'message' => $ex->getMessage()]); } }
Chrome MediaRecorder录制代码
this.recordMicrophone = function(stream) { self.mediaRecorder = new MediaRecorder(stream); self.mediaRecorder.onstop = function(e) { self.$audio.attr('controls',true); let audioBlob = new Blob(self.chunks, { 'type' : 'audio/mpeg; codecs=mp3' }); self.chunks = []; let audioURL = window.URL.createObjectURL(audioBlob); self.$audio.attr('src', audioURL); let recordingName = self.getRecordingName(self.$audio) self.audioBlobs[recordingName] = audioBlob; } self.mediaRecorder.ondataavailable = function(e) { self.chunks.push(e.data); } }
TwiML示例
<Response> <Play>https://xxxxx.s3.amazonaws.com/recordings/dev/prompt-26-87.mp3</Play> <Gather action="/anon/voice.xml/menu-option" input="dtmf speech" method="GET" numDigits="1"> </Gather> </Response>
疑问
- 录制时指定的格式规格是否被浏览器忽略?
- S3是否会根据文件内容自动识别并返回Content-Type?
video/webm是否是<Play>报错的真正原因?- 能否通过Flysystem上传时直接设置文件的MIME类型?(目前已知可通过AWS控制台手动修改)
更新
经过大量测试确认,TwiML <Play>动词仅支持播放真实的WAV和MP3文件,官方文档关于支持格式的描述存在不准确。Chrome的MediaRecorder生成的MP3并非标准MP3,而是无视频轨道的MPEG容器,同样无法被<Play>识别。目前正在研究如何让Chrome录制并保存标准MP3或WAV文件。
内容的提问来源于stack exchange,提问作者AQuirky
相关产品推荐
相关产品推荐

