經過 ffmpeg 無損剪切/拼接視頻

剪切/拼接視頻文件是一種常見需求。在線視頻網站如今每每將一個視頻文件分割成 n 段,以減小流量消耗。使用 DownloadHelper/DownThemAll 這類工具下載下來的每每就是分割後的文件。能實現剪切/拼接視頻文件的工具多種多樣,但每每都須要進行視頻重編碼(transcoding),這就不可避免的帶來了視頻質量上的損耗,更不用提那長的使人髮指的轉換時間了…git

其實藉助 ffmpeg 咱們就能夠在不進行視頻重編碼的狀況下完成此類任務:github

剪切bash

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

其中 START_TIME/STOP_TIME 的格式能夠寫成兩種格式:ide

  1. 以秒爲單位計數: 80
  2. 時:分:秒: 00:01:20

拼接 :工具

拼接的狀況稍微複雜些,咱們須要將須要拼接的視頻文件按如下格式保存在一個列表 list.txt 中:網站

file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'

相應的命令爲:編碼

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

因爲不須要重編碼,這兩條命令幾乎是即時完成的。spa

方便起見,我寫了一個腳原本簡化操做。放在 github 上,請自取:
https://gist.github.com/imcaspar/8771268code

#!/bin/bash
#cut/join videos using ffmpeg without quality loss

if [ -z $1 ] || [ -z $2 ]; then
   echo "Usage:$0 c[ut] seconds <File>"
   echo "   eg. $0 c 10 80 example.mp4"
   echo "   eg. $0 c 00:00:10 00:01:20 example.mp4"
   echo "Usage:$0 j[oin] <FileType>"
   echo "   eg. $0 j avi"
   exit
fi

case "$1" in
   c)
      echo "cuttig video..."
      fileName=$(echo $4 | cut -f 1 -d '.')
      fileType=$(echo $4 | cut -f 2 -d '.')
      ffmpeg -i $4 -ss $2 -t $3 -acodec copy -vcodec copy $fileName-$2-$3.$fileType
      ;;
   j)
      echo "joinning videos..."
      rm temp_list.txt      
      for f in ./*.$2; do echo "file '$f'" >> temp_list.txt; done
      printf "file '%s'\n" ./*.$2 > temp_list.txt
      ffmpeg -f concat -i temp_list.txt -c copy output.$2
      rm temp_list.txt
      ;;
   *)
      echo "wrong arguments"
      ;;
esac
exit

以上拼接操做生效的前提是,全部視頻文件的格式編碼相同,若是須要拼接不一樣格式的視頻文件能夠藉助如下腳本:
https://gist.github.com/imcaspar/8778002視頻

相關文章
相關標籤/搜索