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

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

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

  剪切:

 代码如下  
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 中:

 代码如下  
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'

  相应的命令为:

 代码如下  
ffmpeg -f concat -i **list.txt** -c copy output.mp4

  由于不需要重编码,这两条命令几乎是即时完成的。

  方便起见,我写了一个脚本来简化操作。放在 github 上,请自取:

 代码如下  

#!/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

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

 代码如下  

# change this to what you need !!!
EXTRA_OPTIONS='-vcodec libx264 -crf 23 -preset medium -acodec aac -strict experimental -ac 2 -ar 44100 -ab 128k'
 
################################################################################
#
# NO NEED TO TOUCH ANYTHING AFTER THIS LINE!
#
################################################################################
 
# the version of the script
VERSION=1.3
 
# location of temp folder
TMP=/tmp
 
################################################################################
 
echo "MultiMedia Concat Script v$VERSION (mmcat) - A script to concatenate multiple multimedia files."
echo "Based on FFmpeg - www.ffmpeg.org"
echo "Don't forget to edit this script and change EXTRA_OPTIONS"
echo ""
 
################################################################################
# syntax check (has to have at least 3 params: infile1, infile2, outfile
################################################################################
if [ -z $3 ]; then
 echo "Syntax: $0 <input1> <input2> <input3> ... <output>"
 exit 1
fi
 
################################################################################
# get all the command line parameters, except for the last one, which is output
################################################################################
# $first  - first parameter
# $last   - last parameter (output file)
# $inputs - all the inputs, except the first input, because 1st input is
#           handled separately
################################################################################
first=${@:1:1}
last=${@:$#:1}
len=$(($#-2))
inputs=${@:2:$len}
 
# remove all previous tmp fifos (if exist)
rm -f $TMP/mcs_*
 
################################################################################
# decode first input differently, because the video header does not have to be
# kept for each video input, only the header from the first video is needed
################################################################################
mkfifo $TMP/mcs_a1 $TMP/mcs_v1
 
ffmpeg -y -i $first -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 $TMP/mcs_a1 2>/dev/null </dev/null &
ffmpeg -y -i $first -an -f yuv4mpegpipe -vcodec rawvideo $TMP/mcs_v1 2>/dev/null </dev/null &
 
# if you need to log the output of decoding processes (usually not necessary)
# then replace the "2>/dev/null" in 2 lines above with your log file names, like this:
#ffmpeg -y -i $first -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 $TMP/mcs_a1 2>$TMP/log.a.1 </dev/null &
#ffmpeg -y -i $first -an -f yuv4mpegpipe -vcodec rawvideo $TMP/mcs_v1 2>$TMP/log.v.1 </dev/null &
 
################################################################################
# decode all the other inputs, remove first line of video (header) with tail
# $all_a and $all_v are lists of all a/v fifos, to be used by "cat" later on
################################################################################
all_a=$TMP/mcs_a1
all_v=$TMP/mcs_v1
i=2
for f in $inputs
do
 mkfifo $TMP/mcs_a$i $TMP/mcs_v$i
 
 ffmpeg -y -i $f -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 $TMP/mcs_a$i 2>/dev/null </dev/null &
 { ffmpeg -y -i $f -an -f yuv4mpegpipe -vcodec rawvideo - 2>/dev/null </dev/null | tail -n +2 > $TMP/mcs_v$i ; } &
 
 # if you need to log the output of decoding processes (usually not necessary)
 # then replace the "2>/dev/null" in 2 lines above with your log file names, like this:
 #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 &
 #{ ffmpeg -y -i $f -an -f yuv4mpegpipe -vcodec rawvideo - 2>$TMP/log.v.$i </dev/null | tail -n +2 > $TMP/mcs_v$i ; } &
 
 all_a="$all_a $TMP/mcs_a$i"
 all_v="$all_v $TMP/mcs_v$i"
 let i++
done
 
################################################################################
# concatenate all raw audio/video inputs into one audio/video
################################################################################
mkfifo $TMP/mcs_a_all
mkfifo $TMP/mcs_v_all
cat $all_a > $TMP/mcs_a_all &
cat $all_v > $TMP/mcs_v_all &
 
################################################################################
# finally, encode the raw concatenated audio/video into something useful
################################################################################
ffmpeg -f u16le -acodec pcm_s16le -ac 2 -ar 44100 -i $TMP/mcs_a_all \
       -f yuv4mpegpipe -vcodec rawvideo -i $TMP/mcs_v_all \
 $EXTRA_OPTIONS \
 $last
 
################################################################################
# remove all fifos
################################################################################
rm -f $TMP/mcs_*

时间: 2024-12-03 11:58:13

linux中使用ffmpeg 无损剪切/拼接视频程序的相关文章

Linux中部署FFmpeg开源视频压缩环境过程简单笔记

下面是在Linux中部署FFmpeg和相关类库全过程的简单记录,如下: tar zxvf ./yasm-1.3.0.tar.gz cd yasm-1.3.0 ./configure make make install tar xvfj ./x264.tar.bz2 cd x264 make clean ./configure --enable-shared make make install tar zxvf ./lame-3.99.5.tar.gz cd lame-3.99.5 ./confi

Linux中使用at命令定时执行一个程序

在windows下有一个还算好用的命令:at    它完成的使命是能够定时执行某个任务,例如:在一个月黑风高的晚上,下载一个电影的时候,但是又不想守着,但是一直守着又不可能,不关机就更对不起人类了   所以,在那时就可以使用at命令叫它在3:00关机,那么命令大概如下:at 3:00 shutdown -s -f   具体的怎么玩儿的自己在windows下的cmd黑框框里输入: at   /? 自己看帮助去吧  现在莫有windows环境,给你们截不了图的 当然,Linux也有这么一个叫at的命

LINUX中PHP实现网页截屏实例程序

服务器端 为实现截图的程序必须借助服务器端程序:http://code.google.com/p/wkhtmltopdf/ 可将网页转换为pdf或者图片,32和64位有区别,找个适合自己服务器的版本. 安装 安装过程十分简单:解压 -> 找个合适的路径放下- 执行 命令行调用1  代码如下 复制代码 /servers/app/qtwebkit/wkHtmlToImage 111cn.net www.111cn.net.png 默认的清晰度比较高,图片会很大,生成图片需要一定的时间. php  代

Linux下用FFMPEG采集usb摄像头到RTMP

Linux下用 FFMPEG 采集 usb摄像头视频 和 摄像头内置麦克风音频 到RTMP服务   ffmpeg -f video4linux2 -qscale 10 -r 12 -s 640x480 -i /dev/video0 -f alsa -i hw:1 -ab 16 -ar 22050 -ac 1 -f mp3 -f flv rtmp://127.0.0.1/rtmpsvr/rtmp1

PHP中使用FFMPEG获取视频缩略图和视频总时长实例

  这篇文章主要介绍了PHP中使用FFMPEG获取视频缩略图和视频总时长实例,需要的朋友可以参考下 代码如下: //获得视频文件的缩略图 function getVideoCover($file,$time,$name) { if(empty($time))$time = '1';//默认截取第一秒第一帧 $strlen = strlen($file); // $videoCover = substr($file,0,$strlen-4); // $videoCoverName = $video

linux下ffmpeg 采集1920x1200分辨率视频 导致linux文件系统写保护

问题描述 linux下ffmpeg 采集1920x1200分辨率视频 导致linux文件系统写保护 采集参数:ffmpeg -f video4linux2 -i /dev/video0 -vcodec mpeg4 -b 2000k -r 30 求解答!!!

C#的网页中显示ffmpeg转换视频的进度条

问题描述 C#的网页中显示ffmpeg转换视频的进度条 公司的网站中使用了red视频服务器,后台调用ffmpeg做视频转换,现在想在转换的网页中加一个进度条,搜了很多资料都是winform的进度条.请问有人遇到过这个问题么? 该怎么做.我现在已经在后台代码中取到转换的百分比了,怎么在网页中时时展示呢? 求高人指点.

一个使用FFmpeg库读取3gp视频的例子-Android中使用FFmpeg媒体库(三)

原文:http://doandroid.info/?p=497 在续系列文章在32位的Ubuntu 11.04中为Android NDK r6编译FFmpeg0.8.1版-Android中使用FFmpeg媒体库(一)和在Android中通过jni方式使用编译好的FFmpeg库-Android中使用FFmpeg媒体库(二)文章后,本文将根据github中churnlabs的一个开源项目,来深入展开说明如何使用FFmpeg库进行多媒体的开发. 本文中的代码来自于https://github.com/

Linux 有问必答:如何在Linux 中修复“fatal error: x264.h: No such file or directo

Linux 有问必答:如何在Linux 中修复"fatal error: x264.h: No such file or directo 提问: 我想在Linux中从源码编译视频编码程序.到那时,在编译时,我遇到了一个错误"fatal error: x264.h: No such file or directory",我该如何修复? 下面的编译错误错明你系统中没有x264开发库文件. fatal error: x264.h: No such file or directory