欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

純前端使用ffmpeg實現(xiàn)視頻壓縮的具體方法及踩坑

 更新時間:2023年12月01日 10:03:27   作者:阿熙吧  
這篇文章主要給大家介紹了關(guān)于純前端使用ffmpeg實現(xiàn)視頻壓縮的具體方法及踩坑,要在前端使用FFmpeg進行視頻壓縮,你可以使用FFmpeg的JavaScript,文中通過代碼介紹的非常詳細,需要的朋友可以參考下

實現(xiàn)需求

用戶上傳視頻并壓縮,并且可以選擇壓縮程度,搜索遍各大網(wǎng)站,最終選擇了ffmpeg進行操作。本文包含具體如何實現(xiàn)加上過程中遇到的各種坑

ffmpeg視頻壓縮轉(zhuǎn)碼

ffmpeg視頻壓縮代碼使用很簡單,上代碼

html部分

<h3>視頻前端壓縮</h3>
<video id="output-video" controls></video><br/>
<input type="file" id="uploader">
<p id="message"></p>

 js部分

    // 引入ffmpeg.min.js
    <script src="https://unpkg.com/@ffmpeg/ffmpeg@0.9.5/dist/ffmpeg.min.js"></script>
    <script>
		const { createFFmpeg, fetchFile } = FFmpeg;
		const message = document.getElementById('message');
		const ffmpeg = createFFmpeg({
			log: true,
			progress: ({ ratio }) => {
				message.innerHTML = `完成率: ${(ratio * 100.0).toFixed(2)}%`;
			},
		});
		const transcode = async ({ target: { files }  }) => {
			const { name } = files[0];
			message.innerHTML = '正在加載 ffmpeg-core.js';
			await ffmpeg.load();
			message.innerHTML = '開始壓縮';
            ffmpeg.FS('writeFile', name, await fetchFile(files[0]));
			// '-b','2000000'  值越小  壓縮率越大
			await ffmpeg.run('-i', name,'-b','2000000','output.mp4');
			message.innerHTML = '壓縮完成';
			const data = ffmpeg.FS('readFile', 'output.mp4');
			const video = document.getElementById('output-video');
			video.src = URL.createObjectURL(new Blob([data.buffer], {
				type: 'video/mp4'
			}));
		}
		document.getElementById('uploader').addEventListener('change', transcode);
	</script>

這個ffmpeg大神處理好的cdn我也是找了好久才找到,之前找的各種版本這里就不展示了。

簡單的幾行代碼使用,運行代碼時看著打印的結(jié)果一行一行出來時,一度認為我要成功了,不出意外第一個問題來了。

解決SharedArrayBuffer報錯:

背景:

 又是經(jīng)過一頓搜索,找到以下幾個方案。

1.SharedArrayBuffer 降級 ArrayBuffer

if(!crossOriginIsolated) {
  SharedArrayBuffer = ArrayBuffer;
}

檢查跨域隔離是否生效,你可以檢查 crossOriginIsolated 屬性在窗口和 worker 上下文中是否可用:無法用就降級

使用這個確實解決了SharedArrayBuffer報錯,但是又衍生了另一個錯誤

 error:bad memory    錯誤:內(nèi)存不足

然后又是一頓找解決辦法,太麻煩了解決不了,所以這個方法說了跟沒說一樣。浪費時間

 2.Chrome瀏覽器添加Chrome Origin Trials

1)注冊頁面獲得 Token

        https://developer.chrome.com/origintrials/#/registration

2)Token 放置頁面 meta 標簽或者響應(yīng)頭 Origin-Trial

        http-equiv="origin-trial" content="注冊后獲得的Token"

        <meta http-equiv="origin-trial" content="注冊后獲得的Token">

 最后像這樣:

這個方法就簡單粗暴,但是只支持Chrome瀏覽器,其他瀏覽器一樣還是報錯

3.設(shè)置COOP和COEP頭部

以下所有內(nèi)容都是關(guān)于解決SharedArrayBuffer報錯問題,內(nèi)容有點多,廢話也有點多。都是我遇到的問題,所以記錄下來了。

SharedArrayBuffer - JavaScript | MDN (mozilla.org)

根據(jù)官網(wǎng)給出的解決方案:

 由于我們項目是Think php的,加上我技術(shù)不怎么樣,配置header真不知道在哪里配置。

一頓搜索,于是決定先在本地做測試。我用的是vue2,然后此次本地做的又是另外一個版本了,不過基本上類似。大差不差

1.npm下載ffmpeg資源包

2.上代碼

<template>
    <!-- tempalte部分 -->
    <h3>視頻前端壓縮</h3>
    <video id="output-video" controls :src="vedioSrc"></video><br/>
    <input type="file" id="uploader" @change="initFfmpeg">
    <h5 id="message">{{ message }}</h5>
</template>
<script>
// @ is an alias to /src
//引入
import { createFFmpeg, fetchFile } from "@ffmpeg/ffmpeg";
export default {
    name: "HelloWorld",
    components: {},
    data() {
        return {
            message: null,
            vedioSrc: '',
        };
    },
    methods: {
        //初始化
        initFfmpeg() {
            let file = document.querySelector("#uploader").files[0];
            console.log(file);
            const ffmpeg = createFFmpeg({
                corePath: "ffmpeg-core.js",
                log: true,
            });
            //設(shè)置進度條
            ffmpeg.setProgress(({ ratio }) => {
                console.log(ratio);
                this.percentage = Math.floor(ratio * 100);
            });
            //開始壓縮
            const transcode = async (file) => {
                const { name } = file;
                this.message = "Loading ffmpeg-core.js";
                await ffmpeg.load();
                ffmpeg.FS("writeFile", name, await fetchFile(file));
                this.message = "Start transcoding";
                // '-b','2000000'  值越小  壓縮率越大
                await ffmpeg.run("-i", name, "-b", "700000", "output.mp4");
                this.message = "壓縮完成";
                const data = ffmpeg.FS("readFile", "output.mp4");
                this.fileBytes = data.byteLength;
                //把壓縮后的視頻進行回顯
                this.vedioSrc = URL.createObjectURL(
                    new Blob([data.buffer], { type: "video/mp4" })
                );

            };
            transcode(file);
        },
    },
};
</script>

3.這里走遠了,我們還是要回到主題,解決SharedArrayBuffer問題

我們找到根目錄下的vue.config.js文件

這里就可以配置之前說的解決 SharedArrayBuffer的配置信息

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

然后我們運行代碼 npm run serve...

不出意外,它真的沒出意外。壓縮成功

edeg瀏覽器測試成功,報錯問題解決視頻從6M壓縮到了3M,壓縮效果還是非常不錯的 ,基本上看不出來什么區(qū)別。壓縮清晰度代碼里可以通過 -b '2000000'去調(diào)節(jié),最大就是2000000,值越大壓縮率越大,最小多少不知道,這個可以自己去試。ffmpeg官網(wǎng)有很多使用的方法,功能非常強大。

懷著忐忑的心情去Chrome瀏覽器測試,不出意外,它真的沒出意外。我哭死...

就這樣所有瀏覽器都能成功壓縮視頻,高興之余想到我是在本地做的,而且又是vue項目。上線之后誰也不知道還會有什么錯。

之前我說的我們項目是think php的,我就一菜鳥前端,根本不知道怎么把本地寫的和think php結(jié)合在一起,真的完全搞不懂。

想了半天,沒在本地測試之前不就是解決SharedArrayBuffer它嗎,只要解決了應(yīng)該就沒啥問題。然后我就開始搜索think php怎樣配置header。下面是配置header時遇到的問題

4.配置header信息

第一次是在這個配置文件里面配置的,當然這也是搜索到的。

然后中間各種試錯就不說了。結(jié)論就是這個方法不行

但是?。?!今天試到個方法,它確實可以 

解決SharedArrayBuffer報錯:

我們找到頁面控制器,直接在這里面居然成功了,咱也不是后端咱也不懂

代碼如下:

        header('Cross-Origin-Opener-Policy: same-origin');
        header('Cross-Origin-Embedder-Policy: require-corp');

 這次是真的解決了報錯問題,但是一樣壓縮不成功。原因是:

影響加載跨域資源,如iframe,script標簽加載。你頁面所有的資源將全部不生效。而我又是用的ffmpeg 的cdn,所以直接沒法用。當我下載這個文件下來后,ffmpeg.min.js里面還有cdn鏈接。

差點奔潰了。

廢話說了這么多,最后直接上最終解決辦法。

**重點重點,最后實現(xiàn)方案?。。?!**

那就是通過像本地測試時一樣的方法,用npm下載ffmpeg包

在think php里面使用npm

確保你的開發(fā)環(huán)境已經(jīng)安裝了Node.js和npm。你可以在命令行中輸入node -vnpm -v來檢查它們的安裝情況。

在ThinkPHP 5項目的根目錄下,打開命令行或終端,確保當前目錄位于ThinkPHP項目的根目錄下。

運行以下命令安裝Node.js的包管理器

npm install

如果你需要安裝其他特定的npm包,你可以在項目的根目錄下創(chuàng)建一個package.json文件,并在其中的dependenciesdevDependencies字段中添加所需的依賴項。

我將本地測試時的package.json內(nèi)容直接復(fù)制到項目根目錄創(chuàng)建的package.json上

請注意,ThinkPHP 5本身并不直接與npm交互,而是通過使用前端資源的方式來實現(xiàn)與npm的集成。這意味著你需要在ThinkPHP項目的根目錄下創(chuàng)建一個與前端項目相關(guān)的目錄(例如public/static),并將前端資源放置在該目錄下。然后,你可以在ThinkPHP的模板中使用這些前端資源。

最后就是運行npm install將包下載下來后,在你的代碼中使用

<script type="text/javascript" src="/node_modules/@ffmpeg/ffmpeg/dist/ffmpeg.min.js"></script>

完整代碼

html

            <h3>視頻前端壓縮</h3>
            <video id="output-video" controls></video><br/>
            <input type="file" id="uploader">
            <p id="message"></p>

js

<script type="text/javascript" src="/node_modules/@ffmpeg/ffmpeg/dist/ffmpeg.min.js"></script>
<script>
	const { createFFmpeg, fetchFile } = FFmpeg;
	const message = document.getElementById('message');
	const ffmpeg = createFFmpeg({
		log: true,
		progress: ({ ratio }) => {
			message.innerHTML = `完成率: ${(ratio * 100.0).toFixed(2)}%`;
		},
	});
	const transcode = async ({ target: { files }  }) => {
		const { name } = files[0];
		message.innerHTML = '正在加載 ffmpeg-core.js';
		await ffmpeg.load();
		message.innerHTML = '開始壓縮';
        ffmpeg.FS('writeFile', name, await fetchFile(files[0]));
		// '-b','2000000'  值越小  壓縮率越大
		await ffmpeg.run('-i', name,'-b','2000000','output.mp4');
		message.innerHTML = '壓縮完成';
		const data = ffmpeg.FS('readFile', 'output.mp4');
		const video = document.getElementById('output-video');
		video.src = URL.createObjectURL(new Blob([data.buffer], {
			type: 'video/mp4'
		}));
	}
	document.getElementById('uploader').addEventListener('change', transcode);
</script>

最終解決了,還是需要配置header,無需其他任何的配置。任何瀏覽器都能成功

總結(jié)

到此這篇關(guān)于純前端使用ffmpeg實現(xiàn)視頻壓縮的具體方法及踩坑的文章就介紹到這了,更多相關(guān)前端ffmpeg實現(xiàn)視頻壓縮內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論