ffmpegはWebオンライントランスコーディングと再生を実現します

「オファーが届きました。友達を探して受け取りましょう。私は2022年春の採用チェックインイベントに参加しています。クリックしてイベントの詳細を表示してください。」

前提:会社のプロジェクトでアップロードされたビデオエンコーディング形式は異なりますが、ブラウザの再生では、黒い画面(音声付き)があり、MP4形式のビデオでも再生できません。そのクロムを確認してくださいブラウザのビデオタグ一部の形式のビデオの再生のみをサポートします

通常はこのMP4フォーマットを使用しますが、MP4「1。MPEG4(DivX)」、「2。MPEG4(Xvid)」、「3。」のAVC(H264)3種類に分けられます。このタイプの動画のみを再生H264できますhtml

タグでサポートされているビデオ形式とエンコーディング:

MP4=MPEG 4ファイルはH264ビデオコーデックとAACオーディオコーデックを使用します

WebM=WebMファイルはVP8ビデオコーデックとVorbisオーディオコーデックを使用します

Ogg=OggファイルはTheoraビデオコーデックと Vorbisオーディオコーデックを使用します

フォーマット IE Firefox      オペラ  クロム   サファリ
Ogg    番号 3.5+ 10.5+  5.0以降 番号
MPEG4  9.0+    番号 番号  5.0以降 3.0+
WebM 番号   4.0以降 10.6+   6.0以降 番号

注:ビデオタグは、InternetExplorer8以前ではサポートされていません。

FFMPEGによるトランスコーディング

プレビューアドレス:642134542.github.io/vue-ffmpeg/

1.原則:

ffmpeg.wasmFFmpeg 的纯 WebAssembly / JavaScript 端口。它支持在浏览器内录制、转换和流式传输视频和音频。

Webassembly 的出现为前端转码提供可能

2、按照官网配置

2.1 npm安装

npm install @ffmpeg/ffmpeg @ffmpeg/core
复制代码

2.2 html

<div>

   <h3>Upload a video to transcode to mp4 (x264) and play!</h3>

   <video id="output-video" controls ></video><br/>

   <input type="file" id="uploader">

   <p id="message"></p>

  </div>
复制代码

2.3 js

const { createFFmpeg, fetchFile } = FFmpeg;

const ffmpeg = createFFmpeg({

    corePath: 'https://unpkg.com/@ffmpeg/[email protected]/dist/ffmpeg-core.js',

    log: true,

 });

 const transcode = async ({ target: { files } }) => {

   const message = document.getElementById('message');

     const { name } = files[0];

      message.innerHTML = 'Loading ffmpeg-core.js';

     await ffmpeg.load();

      ffmpeg.FS('writeFile', 'name', await fetchFile(files[0]));

      message.innerHTML = 'Start transcoding';

     await ffmpeg.run('-i', 'name', 'output.mp4');

      message.innerHTML = 'Complete transcoding';

     const data = ffmpeg.FS('readFile', 'output.mp4');

     const video = document.getElementById('output-video');

      video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' }));

   }

   const elm = document.getElementById('uploader');

   elm.addEventListener('change', transcode);
复制代码

3、结果

页面可以正常加载和上传,但是在转码过程中报错了

ReferenceError: SharedArrayBuffer is not defined,

所以需要解决SharedArrayBuffer报错

兼容性查看caniuse.com/?search=Sha…

image.png

可以看到SharedArrayBuffer是支持谷歌浏览器79版本以上

那么,为什么这里会出现SharedArrayBuffer is not defined的报错信息呢

经过一番百度和查看issue, 是因为谷歌浏览器的安全策略机制改变了

2017.7月(Chrome 60)引入 SharedArrayBuffer。

2021.7月(Chrome 92)限制 SharedArrayBuffer只能在 cross-origin isolated 页面使用。

Android Chrome 88 也进行了同样的限制。

从上述结论中,可以知道在60-91的版本的浏览器是可以正常打开的

那么92版本的呢

在vue-cli开发环境中我们可以再vue.config.js中配置

devServer: {
  headers: {
      "Cross-Origin-Opener-Policy": "same-origin",
      "Cross-Origin-Embedder-Policy": "require-corp",
    },
}
复制代码

4、效果

在控制台中可以看到读取文件和转码进程,

而且页面可以正常的显示视频并播放

5、优化:

5.1、corePath

createFFmpeg中的corePath的地址是cdn在线的,这里我们需要换成自己的本地资源,

但是使用import一直报错

估计是相关依赖并没有找到,npm install还是不行

パッケージffmpeg-core.jsffmpeg-core.wasmffmpeg-core.worker.jsを公開する必要がありました

5.2、読み込み

ファイルの読み取りとトランスコードには長い時間がかかるため、読み込みレイヤーとプログレスバーを追加する必要があります

ffmpeg.setProgress(({ ratio }) => {

  console.log(ratio);

  this.percentage = Math.floor(ratio * 100)

  /*

  * ratio is a float number between 0 to 1.

  */

});
复制代码

6.展開:

IPまたはドメイン名アクセスを使用してもエラーが報告されるSharedArrayBuffer is not definedため、プロキシでリクエストヘッダーを構成する必要があります

add_header Cross-Origin-Opener-Policy same-origin;

add_header Cross-Origin-Embedder-Policy require-corp;
复制代码

しかし、それでもエラーメッセージがあります

解決策: 

1.httpの代わりにhttpsを使用します

2.Chromeバージョン60-91を使用してアクセスします

7.エラーメッセージが表示される場合があります

7.1、キャッチ(約束)エラー:おっと、FS操作で問題が発生しました

解決策:中国の名前は使用しないでください。名前をエスケープできます。

7.2、エラー:ffmpeg.FS('readFile'、'output.mp4')エラー。パスが存在するかどうかを確認します

解決策:問題1と同じ

7.3.githubページはヘッダーリクエストヘッダーを設定できません。プレビューアドレスはSharedArrayBufferエラーをどのように解決しますか

この質問には、ソリューションgithub.com/gzuidhof/coを提供するStack Overflowに関する回答があります…開発者は、index.htmlにcoi-serviceworker.jsをインポートするだけで済みます。

<script src="coi-serviceworker.js"></script>
复制代码

参照リンク:

1、juejin.cn /post/701696…

おすすめ

転載: juejin.im/post/7078898276203757581