TS流文件合并

无需软件合并多个TS流文件

Windows&Linux文件合并 原文:http://www.yaosansi.com/post/how-to-combine-files-on-windows-and-linux/

WINDOWS

格式:copy /b <filename1>+<filename2>+…+<filenameN> <filename> 使用方法:假设你有两个文件分别是stream1.ts 和 stream2.ts 那么我们在该目录下输入“copy /b stream1.ts+stream2.ts stream.ts”就可以了,其中stream.ts是你合并后生成的新文件名。

当然,windows也可以使用type命令:

格式:type file1 file2 > file3 Linux 在Linux下同样也能实现文件合并,用“cat”命令就能实现。

格式:cat stream1.ts stream2.ts > stream.ts FFmpeg 以上方法仅适合TS等文件信息保存中文件各个片段的视频格式。而对于文件信息在文件特定部位(如文件头)等视频,直接使用上述方法只是把文件强制的合并到了一起,甚至不能正常播放。

使用ffmpeg的concat可以实现简单的流文件合并功能

ffmpeg -i “concat:01.ts|02.ts” -c copy -y cat.ts 也可以使用文件列表,将需要拼接的视频文件按以下格式保存在一个列表 list.txt 中:

# this is a comment
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'

ffmpeg -f concat -i mylist.txt -c copy output 自动生产文件列表 (将目录中所有.wav文件输出到mylist.txt中)

# with a bash for loop
for f in ./*.wav; do echo "file '$f'" >> mylist.txt; done
# or with printf
printf "file '%s'\n" ./*.wav > mylist.txt

注意:FFmpeg由于只是重新封装,并不会对文件进行重新的编解码,所以速度非常快并且是无损的,但并不意味着适用所有场景。

Shell脚本 合并相同编码文件

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

合并不同编码文件

#!/bin/bash
 
################################################################################
#
# Script name: MultiMedia Concat Script (mmcat)
# Author: burek (burek021@gmail.com)
# License: GNU/GPL, see http://www.gnu.org/copyleft/gpl.html
# Date: 2012-07-14
#
# This script concatenates (joins, merges) several audio/video inputs into one
# final output (just like as if all the inputs were played in a playlist, one
# after another).
#
# All input files must have at least one audio and at least one video stream.
# If not, you can easily add audio silence, using FFmpeg. Just search the
# internet for "ffmpeg add silence".
#
# The script makes use of FFmpeg tool (www.ffmpeg.org) and is free for use under
# the GPL license. The inspiration for this script came from this FAQ item:
# http://ffmpeg.org/faq.html#How-can-I-join-video-files_003f
#
# If you find any bugs, please send me an e-mail so I can fix it.
#
################################################################################
#
# General syntax: mmcat <input1> <input2> <input3> ... <output>
#
# For example: mmcat file1.flv file2.flv output.flv
# would create "output.flv" out of "file1.flv" and "file2.flv".
#
################################################################################
 
# 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_*

参考:

http://trac.ffmpeg.org/wiki/Concatenate https://ffmpeg.org/ffmpeg.html#Stream-copy http://segmentfault.com/a/1190000000414341 https://gist.github.com/imcaspar/8771268 https://gist.github.com/imcaspar/8778002

可以使用以下DOS命令达到目的(即“开始”菜单,“运行”,输入 cmd 再按回车): (此处假设你要合并的高清文件位于 E:\temps 这个位置)

copy/b  E:\temps\*.ts  E:\temps\new.ts

如上,执行该命令后,E:\temps目录下的全部TS文件就被合并成一个new.ts文件了(你原来的那堆文件仍然存在)。

命令解释: 这里使用copy命令的文件合并功能进行ts文件的合并,copy后面的 /b 参数表示把文件按二进制格式来合并,如果不加这个参数,则会把目标当成文本文件来合并,并在文件内添加不必要的标记,这会导致播放出错,所以必须加 /b 参数。 该命令的合并排序是按照你系统下的字母序来的,比如你的文件名是disk1.ts, disk2.ts, disk3.ts,那该命令就会按照disk1.ts+disk2.ts+disk3.ts的顺序来合并这三个文件,事实上,绝大多数网上下载的高清文件,都已经按字母序排列好了,所以你直接执行该命令即可。 上面的例子如果换成diskA.ts, diskB.ts, diskC.ts,该命令仍能正常进行,它会按diskA.ts+diskB.ts+diskC.ts(请统一排序关键字的大小写,即全部用大写A、B、C 或全部用小写a、b、c)。 最好只有一个排序关键字(数字或字母),也就是说各文件名相互间只有一个字符不同,见上面提示。 如果你想万无一失,可以手工把文件名改为1.ts, 2.ts, 3.ts, …..再执行合并。 最后补充两点:
如果你用软件来合并,请注意看软件的说明,有些软件会在合并过程中进行重编码,这可能导致高清文件质量下降。

如果你的高清文件所在硬盘路径太长,请直接将路径复制下来,在Dos命令窗口,待插入的位置上点鼠标右键,选“粘贴”即可,在Dos窗口下不能用 Ctrl+v 来进行粘贴!

可以使用以下DOS命令达到目的(即“开始”菜单,“运行”,输入 cmd 再按回车): (此处假设你要合并的高清文件位于 E:\temps 这个位置)

copy/b  E:\temps\*.ts  E:\temps\new.ts

如上,执行该命令后,E:\temps目录下的全部TS文件就被合并成一个new.ts文件了(你原来的那堆文件仍然存在)。

命令解释: 这里使用copy命令的文件合并功能进行ts文件的合并,copy后面的 /b 参数表示把文件按二进制格式来合并,如果不加这个参数,则会把目标当成文本文件来合并,并在文件内添加不必要的标记,这会导致播放出错,所以必须加 /b 参数。 该命令的合并排序是按照你系统下的字母序来的,比如你的文件名是disk1.ts, disk2.ts, disk3.ts,那该命令就会按照disk1.ts+disk2.ts+disk3.ts的顺序来合并这三个文件,事实上,绝大多数网上下载的高清文件,都已经按字母序排列好了,所以你直接执行该命令即可。 上面的例子如果换成diskA.ts, diskB.ts, diskC.ts,该命令仍能正常进行,它会按diskA.ts+diskB.ts+diskC.ts(请统一排序关键字的大小写,即全部用大写A、B、C 或全部用小写a、b、c)。 最好只有一个排序关键字(数字或字母),也就是说各文件名相互间只有一个字符不同,见上面提示。 如果你想万无一失,可以手工把文件名改为1.ts, 2.ts, 3.ts, …..再执行合并。 最后补充两点:

如果你用软件来合并,请注意看软件的说明,有些软件会在合并过程中进行重编码,这可能导致高清文件质量下降。

如果你的高清文件所在硬盘路径太长,请直接将路径复制下来,在Dos命令窗口,待插入的位置上点鼠标右键,选“粘贴”即可,在Dos窗口下不能用 Ctrl+v 来进行粘贴!