当前位置:首页 > linux教程 > 列表

linux中使用ffmpeg 无损剪切/拼接视频程序

发布:smiling 来源: PHP粉丝网  添加日期:2015-04-28 15:14:30 浏览: 评论:0 

ffmpeg是一款视频处理工具了,我们可以在系统中安装之后利用ffmpeg命令进行视频的处理了,下面就一起来看看吧.

剪切/拼接视频文件是一种常见需求,在线视频网站现在往往将一个视频文件分割成 n 段,以减少流量消耗,使用 DownloadHelper/DownThemAll 这类工具下载下来的往往就是分割后的文件,能实现剪切/拼接视频文件的工具多种多样,但往往都需要进行视频重编码(transcoding),这就不可避免的带来了视频质量上的损耗,更不用提那长的令人发指的转换时间了…

其实借助 ffmpeg 我们就可以在不进行视频重编码的情况下完成此类任务.

剪切代码如下:

  1. ffmpeg -i input.mp4 -ss **START_TIME** -t **STOP_TIME** -acodec copy -vcodec copy output.mp4 

其中 START_TIME/STOP_TIME 的格式可以写成两种格式:

以秒为单位计数: 80

时:分:秒: 00:01:20

拼接:

拼接的情况稍微复杂些,我们需要将需要拼接的视频文件按以下格式保存在一个列表 list.txt 中,代码如下:

  1. file '/path/to/file1' 
  2. file '/path/to/file2' 
  3. file '/path/to/file3' 

相应的命令为如下代码:

ffmpeg -f concat -i **list.txt** -c copy output.mp4

由于不需要重编码,这两条命令几乎是即时完成的,方便起见,我写了一个脚本来简化操作,放在 github 上,请自取,代码如下:

  1. #!/bin/bash 
  2. #cut/join videos using ffmpeg without quality loss 
  3. if [ -z $1 ] || [ -z $2 ]; then 
  4.    echo "Usage:$0 c[ut] seconds <File>" 
  5.    echo "   eg. $0 c 10 80 example.mp4" 
  6.    echo "   eg. $0 c 00:00:10 00:01:20 example.mp4" 
  7.    echo "Usage:$0 j[oin] <FileType>" 
  8.    echo "   eg. $0 j avi" 
  9.    exit 
  10. fi 
  11. case "$1" in 
  12.    c) 
  13.       echo "cuttig video..." 
  14.       fileName=$(echo $4 | cut -f 1 -d '.'
  15.       fileType=$(echo $4 | cut -f 2 -d '.'
  16.       ffmpeg -i $4 -ss $2 -t $3 -acodec copy -vcodec copy $fileName-$2-$3.$fileType 
  17.       ;; 
  18.    j) 
  19.       echo "joinning videos..." 
  20.       rm temp_list.txt       
  21.       for f in ./*.$2do echo "file '$f'" >> temp_list.txt; done 
  22.       printf "file '%s'\n" ./*.$2 > temp_list.txt 
  23.       ffmpeg -f concat -i temp_list.txt -c copy output.$2 
  24.       rm temp_list.txt  //phpfensi.com 
  25.       ;; 
  26.    *) 
  27.       echo "wrong arguments" 
  28.       ;; 
  29. esac 
  30. exit 

以上拼接操作生效的前提是,所有视频文件的格式编码相同,如果需要拼接不同格式的视频文件可以借助以下脚本,代码如下:

  1. # change this to what you need !!! 
  2. EXTRA_OPTIONS='-vcodec libx264 -crf 23 -preset medium -acodec aac -strict experimental -ac 2 -ar 44100 -ab 128k' 
  3.  
  4. ################################################################################ 
  5. # NO NEED TO TOUCH ANYTHING AFTER THIS LINE! 
  6. ################################################################################ 
  7.  
  8. # the version of the script 
  9. VERSION=1.3 
  10.  
  11. # location of temp folder 
  12. TMP=/tmp 
  13.  
  14. ################################################################################ 
  15.  
  16. echo "MultiMedia Concat Script v$VERSION (mmcat) - A script to concatenate multiple multimedia files." 
  17. echo "Based on FFmpeg - www.ffmpeg.org" 
  18. echo "Don't forget to edit this script and change EXTRA_OPTIONS" 
  19. echo "" 
  20.  
  21. ################################################################################ 
  22. # syntax check (has to have at least 3 params: infile1, infile2, outfile 
  23. ################################################################################ 
  24. if [ -z $3 ]; then 
  25.  echo "Syntax: $0 <input1> <input2> <input3> ... <output>" 
  26.  exit 1 
  27. fi 
  28.  
  29. ################################################################################ 
  30. # get all the command line parameters, except for the last one, which is output 
  31. ################################################################################ 
  32. # $first  - first parameter 
  33. # $last   - last parameter (output file) 
  34. # $inputs - all the inputs, except the first input, because 1st input is 
  35. #           handled separately 
  36. ################################################################################ 
  37. first=${@:1:1} 
  38. last=${@:$#:1} 
  39. len=$(($#-2)) 
  40. inputs=${@:2:$len} 
  41.  
  42. # remove all previous tmp fifos (if exist) 
  43. rm -f $TMP/mcs_* 
  44.  
  45. ################################################################################ 
  46. # decode first input differently, because the video header does not have to be 
  47. # kept for each video input, only the header from the first video is needed 
  48. ################################################################################ 
  49. mkfifo $TMP/mcs_a1 $TMP/mcs_v1 
  50.  
  51. ffmpeg -y -i $first -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 $TMP/mcs_a1 2>/dev/null </dev/null & 
  52. ffmpeg -y -i $first -an -f yuv4mpegpipe -vcodec rawvideo $TMP/mcs_v1 2>/dev/null </dev/null & 
  53.  
  54. # if you need to log the output of decoding processes (usually not necessary) 
  55. # then replace the "2>/dev/null" in 2 lines above with your log file names, like this: 
  56. #ffmpeg -y -i $first -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 $TMP/mcs_a1 2>$TMP/log.a.1 </dev/null & 
  57. #ffmpeg -y -i $first -an -f yuv4mpegpipe -vcodec rawvideo $TMP/mcs_v1 2>$TMP/log.v.1 </dev/null & 
  58.  
  59. ################################################################################ 
  60. # decode all the other inputs, remove first line of video (header) with tail 
  61. # $all_a and $all_v are lists of all a/v fifos, to be used by "cat" later on 
  62. ################################################################################ 
  63. all_a=$TMP/mcs_a1 
  64. all_v=$TMP/mcs_v1 
  65. i=2 
  66. for f in $inputs 
  67. do 
  68.  mkfifo $TMP/mcs_a$i $TMP/mcs_v$i 
  69.  
  70.  ffmpeg -y -i $f -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 $TMP/mcs_a$i 2>/dev/null </dev/null & 
  71.  { ffmpeg -y -i $f -an -f yuv4mpegpipe -vcodec rawvideo - 2>/dev/null </dev/null | tail -n +2 > $TMP/mcs_v$i ; } & 
  72.  
  73.  # if you need to log the output of decoding processes (usually not necessary) 
  74.  # then replace the "2>/dev/null" in 2 lines above with your log file names, like this: 
  75.  #ffmpeg -y -i $f -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 $TMP/mcs_a$i 2>$TMP/log.a.$i </dev/null & 
  76.  #{ ffmpeg -y -i $f -an -f yuv4mpegpipe -vcodec rawvideo - 2>$TMP/log.v.$i </dev/null | tail -n +2 > $TMP/mcs_v$i ; } & 
  77.  
  78.  all_a="$all_a $TMP/mcs_a$i" 
  79.  all_v="$all_v $TMP/mcs_v$i" 
  80.  let i++ 
  81. done 
  82.  
  83. ################################################################################ 
  84. # concatenate all raw audio/video inputs into one audio/video 
  85. ################################################################################ 
  86. mkfifo $TMP/mcs_a_all 
  87. mkfifo $TMP/mcs_v_all 
  88. cat $all_a > $TMP/mcs_a_all & 
  89. cat $all_v > $TMP/mcs_v_all & 
  90.  
  91. ################################################################################ 
  92. # finally, encode the raw concatenated audio/video into something useful 
  93. ################################################################################ 
  94. ffmpeg -f u16le -acodec pcm_s16le -ac 2 -ar 44100 -i $TMP/mcs_a_all \ 
  95.        -f yuv4mpegpipe -vcodec rawvideo -i $TMP/mcs_v_all \ 
  96.  $EXTRA_OPTIONS \ 
  97.  $last 
  98.  
  99. ################################################################################ 
  100. # remove all fifos 
  101. ################################################################################ 
  102. rm -f $TMP/mcs_*

Tags: ffmpeg linux剪切

分享到: