激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - PHP教程 - php實現ffmpeg處理視頻的實踐

php實現ffmpeg處理視頻的實踐

2022-01-21 14:58huaweichenai PHP教程

本文主要介紹了php實現ffmpeg處理視頻的實踐,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

最近有一個項目需要使用ffmpeg處理視頻,這里我寫了一個demo,方便我們來實現視頻操作

ffmpeg操作demo

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
<?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;
        }
    }
 
 
    /**
     * 添加視頻文字滾動
     * @param $source string 視頻
     * @param $saveFile string 保存文件
     * @param $text string 水印文字
     * @param array $options 水印樣式
     * @param int $step 每秒步長
     * @param int $star 出現時間
     */
    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 水印開始時間
     * @param null $duration 水印時長
     */
    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 水印開始時間
     * @param null $duration 水印時長
     */
    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 聲音插入延時秒數
     */
    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 剪切開始時間
     * @param null $duration string 剪切時長
     */
    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';
 
    /**
     * 視頻旋轉
     * @param $source string 需要旋轉的視頻
     * @param $saveFile string 旋轉后視頻
     * @param $rotate string 旋轉角度
     */
    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;
    }
 
    /**
     * 視頻轉碼
     * @param $source string 需要轉碼的視頻/音頻
     * @param $saveFile string 轉碼后的視頻/音頻
     */
    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;
    }
 
    /**
     * 創建一個臨時文件
     */
    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 需要獲取時長的資源
     */
    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]; //轉換播放時間為秒數
        }
 
        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),
        ];
    }
}

使用簡單示例

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

1:給視頻添加文字

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ffmpeg = new FfmpegVideo();
$ffmpeg ->titleWater(
    'XXX',//原視頻
    'XXX',//處理后保存視頻
    'XXX',//文字
    [
        'x' => 30,//水平距離
        'y' => 30,//垂直距離
        'fontsize' => 20,//文字大小
        'fontcolor' => 'red',//文字顏色
        'shadowy' => 2,//文字陰影
    ],
    200,//每秒移動步長
    2//文字出現時間(秒)
);

2:將視頻設為靜音

?
1
2
3
4
5
$ffmpeg = new FfmpegVideo();
$ffmpeg->audioMute(
    'XXX',//原視頻
    'XXX',//處理后保存視頻
);

3:視頻裁剪

?
1
2
3
4
5
6
7
$ffmpeg = new FfmpegVideo();
$ffmpeg->clipVideo(
    'XXX',//原視頻
    'XXX',//處理后保存視頻
    0,//裁剪開始時間
    10//裁剪時長
);

4:視頻拼接

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

5:將音頻合并到視頻中

?
1
2
3
4
5
6
7
$ffmpeg = new FfmpegVideo();
$ffmpeg->mergeVideoAudio(
    'XXX',//視頻
    'XXX',//音頻
    'XXX',//處理后保存視頻
    0//音頻插入視頻延時時間(秒)
);

6:獲取視頻信息(長,寬,時長)

?
1
2
3
4
$ffmpeg = new FfmpegVideo();
$ffmpeg->getAttributes(
    'XXX',//視頻
);

到此這篇關于php實現ffmpeg處理視頻的實踐的文章就介紹到這了,更多相關php ffmpeg處理視頻內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://segmentfault.com/a/1190000041122598

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 夜添久久精品亚洲国产精品 | 欧美在线观看黄色 | 中文字幕激情 | 久久影库| 欧美18一19sex性护士农村 | 精品久久久久久久久久久久久久 | 国产大片免费看 | 日日操操| 91精品动漫在线观看 | 狠狠干夜夜草 | 红杏亚洲影院一区二区三区 | 亚洲男人的天堂在线视频 | 日韩视频1 | 日本在线免费观看视频 | 黄色的视频免费观看 | 一本大道av | 欧美乱淫| 亚洲精品无码不卡在线播放he | 香蕉久草在线 | 欧美a欧美 | 青草av.久久免费一区 | 91看片国产 | 新久草视频 | 一区二区免费 | 国产一级在线免费观看 | 国产在线免费 | 一级电影免费 | 久久99久久98精品免观看软件 | 精品偷拍久久 | 久久久www视频 | 国产精品一区视频 | 鲁丝一区二区三区不属 | 国产人成精品一区二区三 | 精品无吗乱吗av国产爱色 | 免费在线观看午夜视频 | 日本www黄色 | 久久国产免费视频 | 日韩视频1 | 国产精品久久久久久久久久大牛 | 色综合久久99| 国产精品久久久久久婷婷天堂 |