HTML5 Источник видео как локально сохраненный блоб больше не работает - PullRequest
4 голосов
/ 05 февраля 2020

Начиная с Chrome 80, похоже, что-то изменилось в работе Blobs или IndexedDB.

Загрузка видеофайла в виде BLOB-объекта и назначение его элементу HTML5 Video через createObjectURL, все еще работает:

// load the blob through XMLHttprequest
RequestAsBlob("https://devserver/some-video.mp4",
function(blob)
{
  video.src = URL.createObjectURL(blob); 

  // same above, video.src is now "blob:https://devserver/36e15718-e597-4859-95d3-6bc39daaa999"
}

video.play();

Вывод: Обещание {} И видео воспроизводится просто отлично.

Осматривая большой двоичный объект, он выглядит так:

Blob {size: 6752122, type: "video/mp4"}
size: 6752122
type: "video/mp4"
__proto__: Blob
arrayBuffer: ƒ arrayBuffer()
size: (...)
slice: ƒ slice()
stream: ƒ stream()
text: ƒ text()
type: (...)
constructor: ƒ Blob()
Symbol(Symbol.toStringTag): "Blob"
get size: ƒ size()
get type: ƒ type()
__proto__: Object

Я использовал для сохранения большого двоичного объекта в IndexedDB (через LocalForage), а затем извлекал его и воспроизводил следующим образом. Это больше не

// blob is a blob fetched from indexedDB
video.src = URL.createObjectURL(blob);  

// video.src is now something like this:
// "blob:https://devserver/ec5e1dfe-0884-40e2-ae8c-c6062734d297"

video.play();

При проверке полученного большого двоичного объекта оно выглядит точно так же, как возвращенное XMLHttpRequest

Однако это не работает:

Вывод: Uncaught (в обещании) DOMException: у элемента нет поддерживаемых источников.

Я не могу понять, что за изменение изменило то, что раньше работало. И это становится более странным:

Если я получу сохраненный BLOB-объект, тот, который, очевидно, больше не может быть привязан к видео sr c напрямую, и я делаю это ...

var url = URL.createObjectURL(cachedblob);

RequestAsBlob(url,
function(blob)
{
 var url = URL.createObjectURL(blob);

 video.src = url;
 video.play();
}

Это работает !! Я ссылаюсь на большой двоичный объект, который был сохранен в indexedDB, создаю для него URL-адрес, снова загружаю его через XMLHttpRequest, как если бы он действительно находился в каком-то удаленном месте, снова получаю его как большой двоичный объект .... и снова создаю URL-адрес для него ... и это работает.

Это не имеет смысла. Я надеюсь, что кто-то может пролить свет на это.

1 Ответ

6 голосов
/ 05 февраля 2020

Можно воспроизвести , даже в Canary build (82) вы прекрасно открыли этот выпуск .

Теперь есть более простые обходные пути, чем выборка через XHR, например, в stable (80) вам просто нужно обернуть полученный BLOB в новый:

video.src = URL.createObjectURL(new Blob( [ blob ] ) ); 

как скрипка , так как StackSnippet ™ не разрешит доступ к IndexedDB.

Однако этот обходной путь работает только в стабильном выпуске (80), в Canary (82) нам нужно фактически прочитать весь BLOB-объект в ArrayBuffer и создать новый BLOB-объект из этого ArrayBuffer:

const buf = await blob.arrayBuffer();
vid.src = URL.createObjectURL( new Blob( [ buf ] ) );

fiddle .
Так как этот последний также работает для стабильного, и мы не знаем, когда они смогут исправить ошибку, вы можете вместо этого использовать второй обходной путь.

1: или дайте мне знать, если вы хотите, чтобы я это сделал.

...