created: 2022-06-16T07:30:02.143Z

FileReader#readAsDataURL で mp4 ファイルが正常に表示されない場合

ブラウザのFileオブジェクト(mp4ファイル)をvideoタグのsrc属性から表示しようとしたら、正常に表示で きる場合とできない場合があった。

正常に閲覧できる readAsDataURL

いつものようにフォームにセットしたFileオブジェクトから FileReader#readAsDataURL で取得した場合。

data:video/mp4;base64,AAAAHGZ....

const asDataUrl = async () => {
    const reader = new FileReader();
    const promise = new Promise((resolve, reject) => {
        reader.onerror = (e) => reject(e);
        reader.onabort = (e) => reject(e);
        reader.onload = (e) => resolve(e.target?.result);
    });
    reader.readAsDataURL(this.file);
    const got = await promise;
    if (typeof got === "string") {
        return got;
    }
}

こうやって取得した readAsDataURLvideo.src に入れるとちゃんと表示できた。

閲覧できない readAsDataURL

ffmpeg.wasm から取り出した Uint8Array をもとにFileオブジェクトを生成すると、video.src に入れてもちゃんと表示されない。

一部抜粋

await this.ffmpeg.run(...args);
const transcoded = this.ffmpeg.FS("readFile", this.ioFiles.o);
const blob = new Blob([transcoded.buffer]);
const file = new File([blob], "");
// そのあとはフォームのときと同様にFileReader#readAsDataURLから取り出し

readAsDataURL の中身はこのようになっていた。

data:application/octet-stream;base64,AAAA...

MIMEが video/mp4 ではない。

解決方法

FileオブジェクトをつくるときにMIMEを設定してあげる必要があった。

const file = new File([blob], "", { type: "video/mp4" });
// video/m4v とかの場合はどうなるんだろう
ホワイトハッカーの教科書
[ad] ホワイトハッカーの教科書
IPUSIRON (単行本(ソフトカバー))