跨境派

跨境派

跨境派,专注跨境行业新闻资讯、跨境电商知识分享!

当前位置:首页 > 国内电商 > 前端ffmpeg压缩视频

前端ffmpeg压缩视频

时间:2024-04-17 09:10:28 来源:网络cs 作者:胡椒 栏目:国内电商 阅读:

标签: 视频 
阅读本书更多章节>>>>

下载ffmpeg

npm install @ffmpeg/core @ffmpeg/ffmpeg

这里需要注意两个插件的版本  "@ffmpeg/core": "^0.10.0",  "@ffmpeg/ffmpeg": "^0.10.1"

配置ffmpeg

安装好插件以后,需要配置一下代码,否则会报错:

1、以VUE为例 在vue.config.js文件中配置请求头

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

2、在页面中实例化ffmpeg的时候可能会报找不到模块儿的错误

const ffmpeg = createFFmpeg({      // ffmpeg路径      corePath: 'ffmpeg-core.js',      // 日志      log: true,      // 进度      progress: ({ ratio }) => {           _this.msg = `完成率: ${(ratio * 100.0).toFixed(1)}%`      }})

因此,最好将下载好的插件文件放到public文件夹里面就可以了

 使用ffmpeg压缩视频

引入ffmpeg
import { createFFmpeg, fetchFile } from '@ffmpeg/ffmpeg'
 文件上传 获取上传的文件
<input id="upload" type="file" accept="video/mp4" capture="camcorder" @change="upload">

注:capture="camcorder" 代表获取手机的摄像头录像   自行查看

实例化ffmpeg
// 实例化ffmpegconst ffmpeg = createFFmpeg({      // ffmpeg路径      corePath: 'ffmpeg-core.js',      // 日志      log: true,      // 进度      progress: ({ ratio }) => {          _this.msg = `完成率: ${(ratio * 100.0).toFixed(1)}%`      }})
压缩视频
await ffmpeg.load()this.msg = '开始压缩'// 把文件加到ffmpeg   写文件ffmpeg.FS('writeFile', name, await fetchFile(file))// await ffmpeg.run('-i', name, '-b', '2000000', '-fs', '4194304', '-preset medium', 'superfast', 'put.mp4')// 开始压缩视频await ffmpeg.run('-i', name, '-b', '2000000', '-crf', '23', '-fs', '4194304', '-s', resolution, 'put.mp4')this.msg = '压缩完成'// 压缩所完成,   读文件  压缩后的文件名称为 put.mp4const data = ffmpeg.FS('readFile', 'put.mp4')

 名词解释:-b: 比特率(也就是速度大小) -crf: 压缩的视频质量   -fs:  把视频压缩到指定大小(有可能会压缩到指定大小,但是可能会剪切指定大小以后的视频片段并删除超出的部分)  -preset medium:  压缩速度    -s: 分辨率  (可以用于指定视频的分辨率  分辨率越大 压缩时间越慢   越小 时间越快)     put.mp4:压缩完成后的文件名称

压缩完的视频格式是blob格式按照需要可以将视频格式转换成file格式,代码如下:
// 类型转换 blob 转换 filetransToFile (data) {    console.log(data)    const _this = this    var file = []    // 转换bolb类型    const blob = new Blob([data], { type: 'text/plain;charset=utf-8' })    // 这么写是因为文件转换是异步任务    const transToFile = async (blob, fileName, fileType) => {        return new window.File([blob], fileName, { type: fileType })    }    const textContain = transToFile(blob, 'put.mp4', 'video/mp4')    // 转换完成后可以将file对象传给接口    textContain.then((res) => {        file.push(res)        console.log('res', res)    })    return file},
如果你嫌压缩的时间太长了,可以控制视频的分辨率   代码如下:
getVideoData () {    return new Promise((resolve, reject) => {        const videoElement = document.getElementById('video')        videoElement.addEventListener('loadedmetadata', function () {            resolve({                width: this.videoWidth,                height: this.videoHeight,                duration: this.duration            })        })    })},

拿到视频的宽高,压缩的时候可以等比缩放一下

这里有个坑值得注意一下:如果页面上没有加载出来视频的话,就不会触发得到视频宽高的,需要先把视频加载出来才行  代码如下:

getObjectURL (file) {    let url = null    window.URL = window.URL || window.webkitURL    if (window.URL) {        url = window.URL.createObjectURL(file)    } else {        url = URL.createObjectURL(file)    }    return url}

献上所有代码

<template>    <div class="video-box">      <video id="video" controls object-fill="fill"></video><br />      <input id="upload" type="file" accept="video/mp4" capture="camcorder" @change="upload">    </div></template><script>import { createFFmpeg, fetchFile } from '@ffmpeg/ffmpeg'export default {    data () {        return {            msg: '',            videoWidth: '',            videoHeight: '',            duration: ''        }    },    methods: {        // 选择文件        async upload (e) {            console.log('start', e)            console.log('start', e.target.files[0])            var _this = this            if (e.target.files[0]) {                var filename = e.target.files[0].name                var filetype = e.target.files[0].type                const videoUrl = _this.getObjectURL(e.target.files[0])                const video = document.getElementById('video')                video.src = videoUrl                this.getVideoData().then((videoObj) => {                    const file = e.target.files[0]                    console.log('videoObj:', videoObj)                    const { width, height } = videoObj                    const result = _this.squeezVideo(file, filename, filetype, width, height, _this.msg)                    result.then(res => {                        console.log('resultFile', res)                    })                })            }        },        // 压缩视频        async squeezVideo (file, filename, filetype, width, height) {            console.log('squeezingVideo file name:  ', file.name)            console.log('squeezingVideo file type:  ', file.type)            console.log('squeezingVideo file path:  ', file.path)            console.log('squeezingVideo file size:  ', file.size)            console.log('squeezingVideo file lastModified:  ', file.lastModified)            console.log('squeezingVideo file lastModifiedDate:  ', file.lastModifiedDate)            const _this = this            // 分辨率            const resolution = `${width / 2}x${height / 2}`            // 实例化ffmpeg            const ffmpeg = createFFmpeg({                // ffmpeg路径                corePath: 'ffmpeg-core.js',                // 日志                log: true,                // 进度                progress: ({ ratio }) => {                    _this.msg = `完成率: ${(ratio * 100.0).toFixed(1)}%`                }            })            var { name } = file            this.msg = '正在加载 ffmpeg-core.js'            // 开始加载            await ffmpeg.load()            this.msg = '开始压缩'            // 把文件加到ffmpeg   写文件            ffmpeg.FS('writeFile', name, await fetchFile(file))            // await ffmpeg.run('-i', name, '-b', '2000000', '-fs', '4194304', '-preset medium', 'superfast', 'put.mp4')            // 开始压缩视频            await ffmpeg.run('-i', name, '-b', '2000000', '-crf', '23', '-fs', '4194304', '-s', resolution, 'put.mp4')            this.msg = '压缩完成'            // 压缩所完成,   读文件  压缩后的文件名称为 put.mp4            const data = ffmpeg.FS('readFile', 'put.mp4')            // 转换压缩后的视频格式  当前为 blob 格式            var filed = _this.transToFile(data)            console.log('transToFile: ', filed)            return new Promise((resolve, reject) => {                if (filed) {                    resolve({                        squzingFile: filed                    })                }            })        },        // 获取视频的宽高分辨率        getVideoData () {            return new Promise((resolve, reject) => {                const videoElement = document.getElementById('video')                videoElement.addEventListener('loadedmetadata', function () {                    resolve({                        width: this.videoWidth,                        height: this.videoHeight,                        duration: this.duration                    })                })            })        },        // 获取上传视频的url        getObjectURL (file) {            let url = null            window.URL = window.URL || window.webkitURL            if (window.URL) {                url = window.URL.createObjectURL(file)            } else {                url = URL.createObjectURL(file)            }            return url        },        // 类型转换 blob 转换 file        transToFile (data) {            console.log(data)            const _this = this            var file = []            // 转换bolb类型            const blob = new Blob([data], { type: 'text/plain;charset=utf-8' })            // 这么写是因为文件转换是异步任务            const transToFile = async (blob, fileName, fileType) => {                return new window.File([blob], fileName, { type: fileType })            }            const textContain = transToFile(blob, 'put.mp4', 'video/mp4')            // 转换完成后可以将file对象传给接口            textContain.then((res) => {                file.push(res)                console.log('res', res)                // _this.confirm(file)            })            return file        }    }}</script>

 可以封装压缩视频代码

目录src/utils/ffmpeg.js
import { createFFmpeg, fetchFile } from '@ffmpeg/ffmpeg'// 压缩视频const squeezVideo = async (file, filename, filetype, width, height) => {    console.log('file', file)    console.log('filename', filename)    console.log('filetype', filetype)    console.log('width', width)    console.log('height', height)    // 分辨率    const resolution = `${width / 2}x${height / 2}`    // 实例化ffmpeg    const ffmpeg = createFFmpeg({        // ffmpeg路径        corePath: 'ffmpeg-core.js',        // 日志        log: true        // 进度        // progress: ({ ratio }) => {        //     msg = `完成率: ${(ratio * 100.0).toFixed(1)}%`        // }    })    console.log('file---', file)    var { name } = file    // msg = '正在加载 ffmpeg-core.js'    // 开始加载    await ffmpeg.load()    // msg = '开始压缩'    // 把文件加到ffmpeg   写文件    ffmpeg.FS('writeFile', name, await fetchFile(file))    // await ffmpeg.run('-i', name, '-b', '2000000', '-fs', '4194304', '-preset medium', 'superfast', 'put.mp4')    // 开始压缩视频    await ffmpeg.run('-i', name, '-b', '2000000', '-crf', '23', '-fs', '4194304', '-s', resolution, 'put.mp4')    // msg = '压缩完成'    // 压缩所完成,   读文件  压缩后的文件名称为 put.mp4    const data = ffmpeg.FS('readFile', 'put.mp4')    // 转换压缩后的视频格式  当前为 blob 格式    var res = transToFile(data, filename, filetype)    return new Promise((result, reject) => {        result({            filed: res        })    })}// 类型转换 blob 转换 fileconst transToFile = (data, filename, filetype) => {    var filed = []    console.log(data)    // 转换bolb类型    const blob = new Blob([data], { type: 'text/plain;charset=utf-8' })    // 这么写是因为文件转换是异步任务    const transToFile = async (blob, fileName, fileType) => {        return new window.File([blob], fileName, { type: fileType })    }    const textContain = transToFile(blob, filename, filetype)    // 转换完成后可以将file对象传给接口    textContain.then((res) => {        filed.push(res)        console.log('res', res)    })    return filed}export { squeezVideo }

注意事项:

ffmpeg是一款很强大的视频编辑工具,你可以自己研究研究,上述的代码可以自己封装一下,另外ffmpeg不能用于微信环境或者是企微环境,代码执行不下去。

效果视频

ffmpeg压缩视频

如果各位视频看不到的话,请移步到我的主页进行观看

 还有一种插件好像可以  video-conversion.js  但是没有找到官网,有小伙伴研究成功的话,踢我一下哈

文章若有不足之处  烦请指正

阅读本书更多章节>>>>

本文链接:https://www.kjpai.cn/guonei/2024-04-17/159680.html,文章来源:网络cs,作者:胡椒,版权归作者所有,如需转载请注明来源和作者,否则将追究法律责任!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。

文章评论