【实战技巧】前端播放本地视频并实现截图功能(中)

ffmpeg.FS

ffmpeg.FS(method, ...args) 用来运行 FS 操作。

对于 ffmpeg.wasm 的输入/输出文件,需要先将它们保存到 MEMFS 以便 ffmpeg.wasm 能够使用它们。这里我们依赖 Emscripten 提供的 FS 方法♂️。

参数如下

  • method: 需要执行的方法名。
  • args: 执行方法对应的参数。
/* Write data to MEMFS, need to use Uint8Array for binary data */
// 把文件存入内存中
ffmpeg.FS('writeFile', 'video.avi', new Uint8Array(...));
/* Read data from MEMFS */
// 在内存中读取
ffmpeg.FS('readFile', 'video.mp4');
/* Delete file in MEMFS */
// 在内存中删除
ffmpeg.FS('unlink', 'video.mp4'); 

ffmpeg.exit

ffmpeg.exit() 用来杀死程序的执行,同时删除 MEMFS 以释放内存。

ffmpeg.setLogging

ffmpeg.setLogging(logging) 控制是否将日志信息输出到控制台。

参数如下

  • logging: 在控制台中打开/关闭日志消息。
ffmpeg.setLogging(true); 

ffmpeg.setLogger

ffmpeg.setLogger(logger) 设置和获取 ffmpeg.wasm 的输出消息。。

参数如下

  • logger: 处理消息的函数。
ffmpeg.setLogger(({ type, message }) => {
  console.log(type, message);
  /*
   * type can be one of following:
   *
   * info: internal workflow debug messages
   * fferr: ffmpeg native stderr output
   * ffout: ffmpeg native stdout output
   */
}); 

ffmpeg.setProgress

ffmpeg.setProgress(progress) 进度处理程序,用于获取 ffmpeg 命令的当前进度。

参数如下

  • progress: 处理进度信息的函数。
ffmpeg.setProgress(({ ratio }) => {
  console.log(ratio);
  /*
   * ratio is a float number between 0 to 1. 0 到 1之间的数字
   */
}); 

fetchFile

fetchFile(media) 返回一个 Promise, 用于从各种资源中获取文件。要处理的视频/音频文件可能位于远程 URL 或本地文件系统中的某个位置。这个函数帮助你获取文件并返回一个 Uint8Array 变量供 ffmpeg.wasm 使用。

参数如下

  • media: URL 字符串、base64 字符串或 FileBlobBuffer 对象。
(async () => {
  const data = await fetchFile('https://github.com/ffmpegwasm/testdata/raw/master/video-3s.avi');
  /*
   * data will be in Uint8Array format
   */
})(); 

补充

设置 corePath

corePath 支持引入 cdn

const ffmpeg = createFFmpeg({
  corePath: 'https://unpkg.com/@ffmpeg/[email protected]/dist/ffmpeg-core.js',
}) 

但是业务需要部署在内网,访问不了 cdn,幸好 corePath 也支持加载本地文件。

这里应该是支持绝对路径,默认会去访问 public 下面的文件。

const ffmpeg = createFFmpeg({
  corePath: 'ffmpeg-core.js',
}) 

node_modules\@ffmpeg\core\dist 下面的三个文件拷贝到 public 中。

【实战技巧】前端播放本地视频并实现截图功能(中)_第1张图片

设置日志

在创建实例的时候,通过传入 log: true,开启日志。

const ffmpeg = createFFmpeg({
  log: true,
}) 

【实战技巧】前端播放本地视频并实现截图功能(中)_第2张图片

也可以通过 ffmpeg.setLogger 自定义日志格式,比如

ffmpeg.setLogger(({ type, message }) => {
  console.log(' ~ message', message);
  console.log(' ~ type', type);
}); 

【实战技巧】前端播放本地视频并实现截图功能(中)_第3张图片

还可以直接在创建实例的时候传入 logger 属性,效果是一样的,建议把 log 属性改为 false,不然日志会重复。

const ffmpeg = createFFmpeg({
  corePath: 'ffmpeg-core.js',
  log: false,
  logger: ({ type, message }) => {
    console.log(' ~ message', message);
    console.log(' ~ type', type);
  }
}) 

获取进度

如何获取上传文件的进度呢,可以通过 ffmpeg.setProgress

ffmpeg.setProgress(({ ratio }) => {
  console.log(' ~ ratio', ratio);
}); 

image.png

也可以直接在创建实例的时候传入 progress 属性,效果是一样的。

const ffmpeg = createFFmpeg({
  corePath: 'ffmpeg-core.js',
  log: false,
  progress: ({ ratio }) => {
    console.log(' ~ ratio', ratio);
  }
}) 

解决错误

如果产生下面这个错误

【实战技巧】前端播放本地视频并实现截图功能(中)_第4张图片

本地开发的时候需要在 vue.config.js 中添加

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

如果是 vite 的项目这样修改 vite.config.ts

 plugins: [
      vue(), 
      vueJsx(),
      {
        name: 'configure-response-headers',
        configureServer: server => {
          server.app.use('/node_modules/',(_req, res, next) => {
            res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');
            res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
            next();
          });
        }
      }
    ], 

部署的时候需要配置 nginx 或者在后端配置。

add_header Cross-Origin-Opener-Policy same-origin; 
add_header Cross-Origin-Embedder-Policy require-corp; 

你可能感兴趣的:(音视频,前端)