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

php實(shí)現(xiàn)ffmpeg處理視頻的實(shí)踐

 更新時(shí)間:2021年12月17日 16:27:54   作者:huaweichenai  
本文主要介紹了php實(shí)現(xiàn)ffmpeg處理視頻的實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

最近有一個(gè)項(xiàng)目需要使用ffmpeg處理視頻,這里我寫了一個(gè)demo,方便我們來(lái)實(shí)現(xiàn)視頻操作

ffmpeg操作demo

<?php

namespace common\helpers;

use common\models\Config;
use common\models\VideoApiLog;
use Yii;
use yii\helpers\ArrayHelper;
use common\helpers\Universal;
use yii\helpers\FileHelper;
use yii\httpclient\Client;
use yii\web\ServerErrorHttpException;

/**
 * ffmpeg視頻處理
 *
 * @author wangjian
 * @since 0.1
 */
class FfmpegVideo
{

    public $ffmpeg = 'ffmpeg';


    public function __construct($ffmpeg = null)
    {
        if ($ffmpeg) {
            $this->ffmpeg = $ffmpeg;
        }
    }


    /**
     * 添加視頻文字滾動(dòng)
     * @param $source string 視頻
     * @param $saveFile string 保存文件
     * @param $text string 水印文字
     * @param array $options 水印樣式
     * @param int $step 每秒步長(zhǎng)
     * @param int $star 出現(xiàn)時(shí)間
     */
    public function titleMod($source, $saveFile, $text, $options = [], $step = 20, $star = 0)
    {
        $command = $this->ffmpeg .' -y -i '. $source .' -async 1 -metadata:s:v:0 start_time=0 -vf ';

        $fonts = Yii::getAlias('@webroot') . "/fonts/simsun.ttc";
        $fonts = str_replace('\\', '/', $fonts);
        $fonts = str_replace(':', '\\:', $fonts);
        $command .= '"drawtext=fontfile=\''. $fonts .'\': text=\''. $text .'\'';

        foreach ($options as $key => $value) {
            $command .= ':' . $key . '=' . $value;
        }

        $command .= ':x=\'if(gte(t,'. $star .'),((t-'. $star .') * '. $step .'),NAN)\'';

        $command .= '" ';
        $command .= $saveFile;
        exec($command, $output, $result_code);
        if ($result_code == 0) {
            return true;
        }
        return  false;
    }


    /**
     * 圖片水印
     * @param $source string 視頻
     * @param $saveFile string 保存文件
     * @param $waterImage string 水印圖片
     * @param $left integer 水印水平位置
     * @param $top integer 水印垂直位置
     * @param null $star 水印開始時(shí)間
     * @param null $duration 水印時(shí)長(zhǎng)
     */
    public function imageWater($source, $saveFile, $waterImage, $left, $top, $star = null, $duration = null)
    {
        $waterImage = str_replace('\\', '/', $waterImage);
        $waterImage = str_replace(':', '\\:', $waterImage);
        $command = $this->ffmpeg . ' -y -i '. $source .' -vf "movie=\''. $waterImage .'\'[watermark];';
        $command .= '[in][watermark] overlay='. $left .':'. $top;
        if ($star) {
            $end = ($duration) ? $star + $duration : $star;
            $command .= ':enable=\'between(t,'. $star .','. $end .')\'';
        }
        $command .= '[out] " ' . $saveFile;
        exec($command, $output, $result_code);
        if ($result_code == 0) {
            return true;
        }
        return  false;
    }


    /**
     * 給視頻添加文字水印
     * @param $source string 視頻
     * @param $saveFile string 保存文件
     * @param $text string 水印文字
     * @param array $options 水印樣式
     * @param null $star 水印開始時(shí)間
     * @param null $duration 水印時(shí)長(zhǎng)
     */
    public function titleWater($source, $saveFile, $text, $options = [], $star = null, $duration = null)
    {
        $command = $this->ffmpeg .' -y -i '. $source .' -vf ';
        $fonts = Yii::getAlias('@webroot') . "/fonts/STZHONGS.TTF";
        $fonts = str_replace('\\', '/', $fonts);
        $fonts = str_replace(':', '\\:', $fonts);
        $command .= '"drawtext=fontfile=\''. $fonts .'\': text=\''. $text .'\'';

        foreach ($options as $key => $value) {
            $command .= ':' . $key . '=' . $value;
        }
        if ($star) {
            $end = ($duration) ? $star + $duration : $star;
            $command .= ':enable=\'between(t,'. $star .','. $end .')\'';
        }
        $command .= '" ';
        $command .= $saveFile;

        exec($command, $output, $result_code);
        if ($result_code == 0) {
            return true;
        }
        return  false;
    }

    /**
     * 將音頻合并到視頻中
     * @param $videoFile string 視頻文件
     * @param $audioFile string 音頻文件
     * @param $saveFile string 保存文件
     * @param $delay integer 聲音插入延時(shí)秒數(shù)
     */
    public function mergeVideoAudio($videoFile, $audioFile, $saveFile, $delay = null)
    {
        $delayTime = 0;
        if ($delay) {
            $delayTime = $delay * 1000;
        }
        $command =  $this->ffmpeg . ' -y -i '. $audioFile .' -i '. $videoFile .' -c:v copy -c:a aac -strict experimental -filter_complex "[0]adelay='. $delayTime .'|'. $delayTime .'[del1],[1][del1]amix" ' . $saveFile;
        exec($command, $output, $result_code);
        if ($result_code == 0) {
            return true;
        }
        return  false;
    }


    /**
     * 靜音
     */
    public function audioMute($source, $saveFile)
    {
        $command =  $this->ffmpeg . ' -y -i '. $source .' -filter:a "volume=0" ' . $saveFile;
        exec($command, $output, $result_code);
        if ($result_code == 0) {
            return true;
        }
        return  false;
    }


    /**
     * 提取視頻的音頻
     * @param $source string 需要提取聲音的視頻
     * @param $saveFile string 提取聲音后保存的音頻
     * @return bool
     */
    public function collectAudio($source, $saveFile)
    {
        $command =  $this->ffmpeg . ' -y -i '. $source .' -vn -acodec copy ' . $saveFile;
        exec($command, $output, $result_code);
        if ($result_code == 0) {
            return true;
        }
        return  false;
    }

    /**
     * 去除視頻聲音
     * @param $source string 需要去除聲音的視頻
     * @param $saveFile string 去除聲音后保存的視頻
     */
    public function removeAudio($source, $saveFile)
    {
        $command =  $this->ffmpeg . ' -y -i '. $source .' -an ' . $saveFile;

        exec($command, $output, $result_code);
        if ($result_code == 0) {
            return true;
        }
        return  false;
    }

    /**
     * 視頻拼接
     * @param $sources array 需要拼接的視頻/音頻
     * @param $saveFile string 拼接后的視頻/音頻
     */
    public function spliceVideo($sources, $saveFile)
    {
        $commands = [];
        $temporaryFile = [];
        $basePath = sys_get_temp_dir();
        $index = 0;
        foreach ($sources as $i => $source) {
            $file = $basePath . '/' . $i . '.ts';
            $commands[$index] = $this->ffmpeg . ' -y -i '. $source .' -vcodec copy -acodec copy -vbsf h264_mp4toannexb ' . $file;
            $temporaryFile[] = $file;
            $index++;
        }
        $commands[$index] = $this->ffmpeg . ' -y -i "concat:'. implode('|', $temporaryFile) .'"  -acodec copy -vcodec copy -absf aac_adtstoasc ' . $saveFile;
        foreach ($commands as $command) {
            exec($command, $output, $result_code);
        }

        foreach ($temporaryFile as $file) {
            @unlink($file);
        }
        return true;

    }


    /**
     * 視頻剪切
     * @param $source string 需要剪切視頻/音頻
     * @param $saveFile string 剪切后保存視頻/音頻
     * @param $star string 剪切開始時(shí)間
     * @param null $duration string 剪切時(shí)長(zhǎng)
     */
    public function clipVideo($source, $saveFile, $star, $duration = null)
    {
        $command = $this->ffmpeg . ' -y -ss '. $star;
        if ($duration) {
            $command .= ' -t '. $duration;
        }
        $command .= ' -i '. $source .' -acodec copy ' . $saveFile;
        exec($command, $output, $result_code);
        if ($result_code == 0) {
            return true;
        }
        return  false;
    }

    const ROTATE_90 = 'transpose=1';
    const ROTATE_180 = 'hflip,vflip';
    const ROTATE_270 = 'transpose=2';

    /**
     * 視頻旋轉(zhuǎn)
     * @param $source string 需要旋轉(zhuǎn)的視頻
     * @param $saveFile string 旋轉(zhuǎn)后視頻
     * @param $rotate string 旋轉(zhuǎn)角度
     */
    public function transposeVideo($source, $saveFile, $rotate)
    {

        $command = $this->ffmpeg . ' -y -i ' . $source . ' -vf ""transpose=1"" ' . $saveFile;
        exec($command, $output, $result_code);
        if ($result_code == 0) {
            return true;
        }
        return  false;
    }

    /**
     * 視頻轉(zhuǎn)碼
     * @param $source string 需要轉(zhuǎn)碼的視頻/音頻
     * @param $saveFile string 轉(zhuǎn)碼后的視頻/音頻
     */
    public function acodecVideo($source, $saveFile)
    {
        $command = $this->ffmpeg . ' -y -i '. $source .' -acodec copy -vcodec copy -f mp4 ' . $saveFile;
        exec($command, $output, $result_code);
        if ($result_code == 0) {
            return true;
        }
        return  false;
    }

    /**
     * 視頻拼接
     * @param $sources array 需要拼接的視頻/音頻
     * @param $saveFile string 拼接后的視頻/音頻
     */
    public function concatVideo($sources, $saveFile)
    {
        $file = $this->createTemporaryFile();
        $fileStream = @fopen($file, 'w');
        if($fileStream === false) {
            throw new ServerErrorHttpException('Cannot open the temporary file.');
        }

        $count_videos = 0;
        if(is_array($sources) && (count($sources) > 0)) {
            foreach ($sources as $videoPath) {
                $line = "";
                if($count_videos != 0)
                    $line .= "\n";
                $line .= "file '". str_replace('\\','/',$videoPath) ."'";

                fwrite($fileStream, $line);
                $count_videos++;
            }
        }
        else {
            throw new ServerErrorHttpException('The list of videos is not a valid array.');
        }

        $command = $this->ffmpeg .' -y -f concat -safe 0 -i '. $file . ' -c copy ' . $saveFile;
        exec($command, $output, $result_code);
        fclose($fileStream);
        @unlink($file);//刪除文件
        if ($result_code == 0) {
            return true;
        }
        return  false;
    }

    /**
     * 創(chuàng)建一個(gè)臨時(shí)文件
     */
    public function createTemporaryFile()
    {
        $basePath = sys_get_temp_dir();
        if (false === $file = @tempnam($basePath, null)) {
            throw new ServerErrorHttpException('Unable to generate a temporary filename');
        }
        return $file;
    }

    /**
     * 獲取視頻信息
     * @param $source string 需要獲取時(shí)長(zhǎng)的資源
     */
    public function getAttributes($source)
    {
        ob_start();
        $command = $this->ffmpeg . ' -i "'. $source .'" 2>&1';
        passthru($command);
        $getContent = ob_get_contents();
        ob_end_clean();
        $duration = 0;
        $widht = 0;
        $height = 0;
        if (preg_match("/Duration: (.*?), start: (.*?), bitrate: (\d*) kb\/s/", $getContent, $match)) {
            $matchs = explode(':', $match[1]);
            $duration = $matchs[0] * 3600 + $matchs[1] * 60 + $matchs[2]; //轉(zhuǎn)換播放時(shí)間為秒數(shù)
        }

        if (preg_match("/Video: (.*?), (.*?), (.*?)[,\s]/", $getContent, $match)) {
            $matchs = explode('x', $match[3]);
            $widht = $matchs[0];
            $height = $matchs[1];
        }

        return [
            'duration' => intval($duration),
            'widht' => intval($widht),
            'height' => intval($height),
        ];
    }
}

使用簡(jiǎn)單示例

這里注意如果無(wú)法執(zhí)行ffmpeg,實(shí)例化時(shí)需要傳入ffmpeg的安裝地址,例如linux下ffmpeg安裝地址為/usr/local/ffmepg,那么實(shí)例化時(shí)需要傳入/usr/local/ffmpeg/bin/ffmpeg

1:給視頻添加文字

$ffmpeg = new FfmpegVideo();
$ffmpeg ->titleWater(
    'XXX',//原視頻
    'XXX',//處理后保存視頻
    'XXX',//文字
    [
        'x' => 30,//水平距離
        'y' => 30,//垂直距離
        'fontsize' => 20,//文字大小
        'fontcolor' => 'red',//文字顏色
        'shadowy' => 2,//文字陰影
    ],
    200,//每秒移動(dòng)步長(zhǎng)
    2//文字出現(xiàn)時(shí)間(秒)
);

2:將視頻設(shè)為靜音

$ffmpeg = new FfmpegVideo();
$ffmpeg->audioMute(
    'XXX',//原視頻
    'XXX',//處理后保存視頻
);

3:視頻裁剪

$ffmpeg = new FfmpegVideo();
$ffmpeg->clipVideo(
    'XXX',//原視頻
    'XXX',//處理后保存視頻
    0,//裁剪開始時(shí)間
    10//裁剪時(shí)長(zhǎng)
);

4:視頻拼接

$ffmpeg = new FfmpegVideo();
$ffmpeg->concatVideo(
    ['XXX', 'XXX'],//需要拼接的視頻
    'XXX',//處理后保存視頻
);

5:將音頻合并到視頻中

$ffmpeg = new FfmpegVideo();
$ffmpeg->mergeVideoAudio(
    'XXX',//視頻
    'XXX',//音頻
    'XXX',//處理后保存視頻
    0//音頻插入視頻延時(shí)時(shí)間(秒)
);

6:獲取視頻信息(長(zhǎng),寬,時(shí)長(zhǎng))

$ffmpeg = new FfmpegVideo();
$ffmpeg->getAttributes(
    'XXX',//視頻
);

到此這篇關(guān)于php實(shí)現(xiàn)ffmpeg處理視頻的實(shí)踐的文章就介紹到這了,更多相關(guān)php ffmpeg處理視頻內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • thinkPHP5框架分頁(yè)樣式類完整示例

    thinkPHP5框架分頁(yè)樣式類完整示例

    這篇文章主要介紹了thinkPHP5框架分頁(yè)樣式類,結(jié)合完整實(shí)例形式分析了thinkPHP5帶css樣式控制的分頁(yè)類定義與簡(jiǎn)單使用方法,需要的朋友可以參考下
    2018-09-09
  • 基于php偽靜態(tài)的實(shí)現(xiàn)詳細(xì)介紹

    基于php偽靜態(tài)的實(shí)現(xiàn)詳細(xì)介紹

    本篇文章介紹了,基于php偽靜態(tài)的實(shí)現(xiàn)詳細(xì)分析。需要的朋友參考下
    2013-04-04
  • CakePHP的安裝的簡(jiǎn)單方法

    CakePHP的安裝的簡(jiǎn)單方法

    在本篇文章里小編給大家整理的是一篇關(guān)于CakePHP的安裝的簡(jiǎn)單方法,對(duì)此有興趣的朋友們可以參考學(xué)習(xí)下。
    2021-01-01
  • thinkPHP事務(wù)操作簡(jiǎn)單案例分析

    thinkPHP事務(wù)操作簡(jiǎn)單案例分析

    這篇文章主要介紹了thinkPHP事務(wù)操作,結(jié)合簡(jiǎn)單案例形式分析了thinkPHP事務(wù)操作的基本原理與使用方法,需要的朋友可以參考下
    2019-10-10
  • PHP+MySql實(shí)現(xiàn)一個(gè)簡(jiǎn)單的留言板

    PHP+MySql實(shí)現(xiàn)一個(gè)簡(jiǎn)單的留言板

    留言板是接觸WEB開發(fā)的基礎(chǔ),寫一個(gè)留言板需要知道前端的一些基礎(chǔ)標(biāo)簽,對(duì)數(shù)據(jù)庫(kù)有一個(gè)了解會(huì)基礎(chǔ)SQL語(yǔ)言,PHP基礎(chǔ)知識(shí),前段基礎(chǔ)+數(shù)據(jù)庫(kù)基礎(chǔ)+PHP基礎(chǔ)=>留言板
    2020-07-07
  • tp5框架使用composer實(shí)現(xiàn)日志記錄功能示例

    tp5框架使用composer實(shí)現(xiàn)日志記錄功能示例

    這篇文章主要介紹了tp5框架使用composer實(shí)現(xiàn)日志記錄功能,結(jié)合實(shí)例形式分析了thinkPHP5框架composer安裝及日志記錄相關(guān)操作技巧,需要的朋友可以參考下
    2019-01-01
  • thinkphp框架使用JWTtoken的方法詳解

    thinkphp框架使用JWTtoken的方法詳解

    這篇文章主要介紹了thinkphp框架使用JWTtoken的方法,結(jié)合實(shí)例形式分析了JWTtoken的功能、原理及thinkPHP使用JWTtoken實(shí)現(xiàn)簽名驗(yàn)證的相關(guān)操作技巧,需要的朋友可以參考下
    2019-10-10
  • php實(shí)現(xiàn)表單提交上傳文件功能

    php實(shí)現(xiàn)表單提交上傳文件功能

    這篇文章主要為大家詳細(xì)介紹了php實(shí)現(xiàn)表單提交上傳文件功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • 基于laravel-admin 后臺(tái) 列表標(biāo)簽背景的使用方法

    基于laravel-admin 后臺(tái) 列表標(biāo)簽背景的使用方法

    今天小編就為大家分享一篇基于laravel-admin 后臺(tái) 列表標(biāo)簽背景的使用方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-10-10
  • phpstorm遠(yuǎn)程連接服務(wù)器并實(shí)時(shí)更新發(fā)布代碼(thinkphp6.0.7)

    phpstorm遠(yuǎn)程連接服務(wù)器并實(shí)時(shí)更新發(fā)布代碼(thinkphp6.0.7)

    這篇文章主要介紹了phpstorm遠(yuǎn)程連接服務(wù)器并實(shí)時(shí)更新發(fā)布代碼(thinkphp6.0.7),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03

最新評(píng)論