В Safari 14.0.2 обработчик доступных данных MediaRecorder захватывает пустой большой двоичный объект

#javascript #safari #web-mediarecorder

Вопрос:

Я использовал API MediaRecorder для записи сеанса веб-камеры из Safari (v14.0.2). Он handleDataAvailable будет собирать потоковые данные каждые 500 мс и помещать большой двоичный объект в recordedBlobs массив.

 this.recordedBlobs = []
this.mediaRecorder = new window.MediaRecorder(this.stream, {mimeType: "video/mp4;codecs=avc1"})
this.mediaRecorder.addEventListener('stop', this.handleStop)
this.mediaRecorder.addEventListener('error', this.handleError)
this.mediaRecorder.addEventListener(
  'dataavailable',
  this.handleDataAvailable
)
this.mediaRecorder.start(500) // Collect blob data every 500ms

handleDataAvailable = (event) => {
  this.recordedBlobs.push(event.data)
}
 

Но из журнала консоли я заметил, что некоторые большие двоичные объекты будут иметь размер 0 и тип «». Пустой большой двоичный объект появляется случайным образом; иногда его нет, иногда внутри массива их много.

Это создает еще большую проблему 👉 когда я объединяю все большие двоичные объекты, чтобы создать совершенно новый большой двоичный объект, новый большой двоичный объект поврежден. В следующем случае 2-й большой двоичный объект имеет размер 0, продолжительность каждого большого двоичного объекта составляет 500 мс, видео должно длиться 5 секунд, но я могу воспроизвести только первые 500 мс.

Проблема возникает только в Safari, Chrome работает нормально. Любые указатели будут действительно оценены по достоинству!

 Array (11)
0 Blob {size: 402074, type: "video/mp4", slice: function, text: function, arrayBuffer: function}
1 Blob {size: 0, type: "", slice: function, text: function, arrayBuffer: function}
2 Blob {size: 726104, type: "video/mp4", slice: function, text: function, arrayBuffer: function}
3 Blob {size: 355672, type: "video/mp4", slice: function, text: function, arrayBuffer: function}
4 Blob {size: 374119, type: "video/mp4", slice: function, text: function, arrayBuffer: function}
5 Blob {size: 369714, type: "video/mp4", slice: function, text: function, arrayBuffer: function}
6 Blob {size: 378604, type: "video/mp4", slice: function, text: function, arrayBuffer: function}
7 Blob {size: 381219, type: "video/mp4", slice: function, text: function, arrayBuffer: function}
8 Blob {size: 434928, type: "video/mp4", slice: function, text: function, arrayBuffer: function}
9 Blob {size: 359651, type: "video/mp4", slice: function, text: function, arrayBuffer: function}
10 Blob {size: 217731, type: "video/mp4", slice: function, text: function, arrayBuffer: function}
 

Комментарии:

1. Пустой большой двоичный объект в середине не должен быть проблемой для последнего большого двоичного объекта, можете ли вы показать, как вы объединяете это?

2. Я просто звоню new window.Blob(this.recordedBlobs, {type: "video/mp4;codecs=avc1"}) . Я думаю, что большой двоичный объект не должен быть пустым, потому dataavailable что он будет запускаться каждые 500 мс и будет создан новый большой двоичный объект. Если размер равен 0, это означает, что он ничего не записал. я прав?

3. Нет, это просто означает, что они не думали, что в поток поступило достаточно информации, чтобы она стоила своего собственного куска. Если вы посмотрите на свой скриншот, третий фрагмент примерно в два раза больше, чем другие -> данные, которые вы ожидали получить во втором фрагменте, попали в третий. И в связи с вашей ошибкой, как вы определяете, что видео повреждено? Ваш тип mime неверен для создания большого двоичного объекта, поэтому, если вы попытаетесь прочитать этот большой двоичный объект из <видео>, это не сработает, это должно быть <видео> new Blob(this.recordedBlobs, {type: "video/mp4"}) . И Фу-у-у, это отлично работает на моем сафари.

4. Я изменил тип на video/mp4 , но все равно, когда я пытался воспроизвести видео window.URL.createObjectURL(videoBlob) , оно всегда останавливалось на отметке времени, где большой двоичный объект имеет размер 0 🙁

5. Просто обновление, я попробовал 14.1.2, без проблем! Поэтому я думаю, что это какая-то устаревшая ошибка в старой версии.