2021 Mar. 14.
2020 Apr. 19.
2020 Apr. 18.
コマンドラインに与えられたMPEG2ファイルを解像度を落としたH.264に変換
ts2h264ffmpeg.sh
#!/bin/bash # 2020 Apr. 19. # 2010 Jun. 11. # Ryuichi Hashimoto. # Convert mpeg2-ts-video to H.264 codec of 800x450 and AAC codec. # Usage: COMMAND INFILE [...] # INFILE codec type : MPEG2-file." # Outfile-name : INFILE.mp4. # But INFILE(abc.mp4) -> OUTFILE(abc.mp4) # # This program uses ffmpeg, tssplitter_lite. # # Change "NewX=MAX-WIDTH-VALUE" in the script to change max width of a converted video. # # Filename of converted video is "original video basefilename+SID.mp4" # # Put libx264-ts-good.ffpreset in any directory and tell the directory in the script. # ### libx264-ts-good.ffpreset ### ### (remove "# " of head of each line) ### # level=41 # crf=25 # coder=1 # flags=+loop # cmp=+chroma # partitions=+parti8x8+parti4x4+partp8x8+partb8x8 # me_method=umh # subq=7 # me_range=16 # g=250 # keyint_min=25 # sc_threshold=40 # i_qfactor=0.71 # b_strategy=1 # qmin=10 # rc_eq=’blurCplx^(1-qComp)’ # bf=16 # bidir_refine=1 # refs=6 ################################ Cmdname=`\basename $0` NewX=870 CPU_CORES=$(/usr/bin/getconf _NPROCESSORS_ONLN) FFMPEGCMD='ffmpeg' # FFMPEGpresetfile='/YOUR/FFMPEG/PRESET/DIR/libx264-ts-good.ffpreset' FFMPEGpresetfile='/usr/local/my/ffmpeg/libx264-ts-good.ffpreset' TmpStr=`which ${FFMPEGCMD}` if [ ${#TmpStr} -lt 1 ]; then \echo "${FFMPEGCMD} is not installed." 1>&2 \exit 1 fi TmpStr=`\which tssplitter_lite` if [ ${#TmpStr} -lt 1 ]; then \echo "tssplitter_lite is not installed." 1>&2 \exit 1 fi # function function usage() { cat << EOP Usage: $Cmdname INFILE [...] INFILE codec type : MPEG2-file. Outfile-name : INFILE.mp4. But INFILE(abc.mp4) -> OUTFILE(abc.mp4) STANDARD-OUT: successfully converted filenames Convert mpeg2-ts-video to H.264 codec of 800x450 and AAC codec. EOP } # function # get resolution of movie. getResolut(){ Resolut=`${FFMPEGCMD} -i ${infileTmp} 2>&1 | \grep -oP '\d\d+x\d\d+'` ResolutX=`\echo $Resolut | \grep -oP '^\d\d+'` ResolutY=`\echo $Resolut | \grep -oP '\d\d+$'` # x-size of resolution is ResolutX # y-size of resolution is ResolutY # by the result of above routine. } # function getNewResolution(){ # get resolution for new video. getResolut # NewX : max length of x-width while [[ NewX -gt 100 ]]; do NewY=$(( NewX * ResolutY / ResolutX )) # NewYが小数点以下を有するかどうかチェック NewYReal=`\echo "scale=5; $NewY + 0.00000" | \bc` NewY2=`\echo "scale=5; $NewX * $ResolutY / $ResolutX" | \bc` if [[ $NewYReal = $NewY2 ]]; then # NewYが奇数ではffmpegでの動画変換が失敗する if [ `expr $NewY % 2` == 0 ]; then # 偶数 \break fi fi NewX=$(( NewX - 10 )) done if [[ $NewX -lt 101 ]]; then \echo "Could not get the resolution for new video of ${infileTmp}." 2>&1 \continue fi # x-size of resolution for new video is NewX # y-size of resolution for new video is NewY # by the result of above routine. } # function convert2h264(){ ${FFMPEGCMD} -y -i ${infileTmp} -f mp4 -vcodec libx264 -fpre ${FFMPEGpresetfile} -r 30000/1001 -aspect 16:9 -s ${NewX}x${NewY} -bufsize 20000k -maxrate 25000k -acodec aac -absf aac_adtstoasc -strict -2 -threads $CPU_CORES $outfileTmp Result=$? if [ $Result -eq 0 ]; then \echo "${outfileTmp}" else if [ -f $outfileTmp ]; then \rm -f $outfileTmp fi \echo "Failed H.264 converting." 1>&2 fi } ############ ### main ### ############ # display usage when no args if [ $# -lt 1 ]; then usage 1>&2 \exit 1 fi # get filenames in array infiles=($@) for fname in ${infiles[@]} do if [ ! -f $fname ]; then \echo "$fname does not exist." 1>&2 \continue fi # Ignore BS-campus-program(*BS11*) because converting this kind of files to mp4 would fail. \echo $fname | \grep -q BS11 Result=$? if [[ 0 = $Result ]]; then \continue fi infile=$fname outfile=${infile}.mp4 # check if video codec is mpeg2 # ( ${FFMPEGCMD} -i $infile 1> /dev/null ) 2>&1 | \egrep ': Video: ' | \egrep -q 'mpeg2video' if [ $? -ne 0 ]; then \echo "$infile is not mpeg2video." 1>&2 \continue fi # get SIDs and convert each SID-program to H.264. SIDs=`${FFMPEGCMD} -i ${infile} 2>&1 | \get_high-resolution-sids_by_ffmpeg.awk` CountSID=`\echo $SIDs | \wc -w` if [ $CountSID -eq 1 ]; then infileTmp=${infile} getResolut if [ $ResolutX -lt 1000 ]; then # In case of small resolution movie, not change resolution NewX=$ResolutX NewY=$ResolutY else getNewResolution fi # convert to H.264 outfileTmp="${infile}-${SIDs}.mp4" convert2h264 elif [ $CountSID -gt 1 ]; then for SID in $SIDs do # ts-split \tssplitter_lite ${infile} "${infile}-${SID}.ts" ${SID} infileTmp="${infile}-${SID}.ts" getResolut if [ $ResolutX -lt 1000 ]; then # In case of small resolution movie, not change resolution NewX=$ResolutX NewY=$ResolutY else getNewResolution fi # convert to H.264. outfileTmp="${infile}-${SID}.mp4" convert2h264 done else echo "${infile} has no video." 1>&2 \continue fi done \exit 0
ts2h264ffmpeg.shを使ってカレントディレクトリ内のMPEG2ファイルをH.264に変換
tss2h264s-ffmpeg.sh
#!/bin/bash # 2020 Apr. 18. # 2011 May 07. # ryuichi Hashimoto. # # Convert EPGREC-type-filename-video to H.264-files in current directory. # If there are plural files of almost same filename, no process works. # ts2h264${FFMPEGCMD}.sh is required. # specifications of converted files depend on ts2h264${FFMPEGCMD}.sh. # STNDARD-OUT: (depends on ts2h264${FFMPEGCMD}.sh) CMDNAME=`basename $0` FFMPEGCMD='ffmpeg' FILE1='tmpls1.txt' FILE2='tmpls2.txt' N=0 umask 0000 function usage() { cat << EOP Usage: $CMDNAME Convert EPGREC-type-filename-video to H.264-files in current directory. If there are plural files of almost same filename, no process works. ts2h264${FFMPEGCMD}.sh is required. specifications of converted files depend on ts2h264${FFMPEGCMD}.sh. STNDARD-OUT: (depends on ts2h264${FFMPEGCMD}.sh) EOP } ************ *** main *** ************ if [ $# -gt 0 ]; then usage 1>&2 \exit 1 fi \ls > $FILE1 \ls > $FILE2 ## カレントディレクトリ内のファイル名を総当たりしてmpeg2をH.264にする # カレントディレクトリ内のファイル名を配列tmparyに格納する \mapfile tmpary < $FILE1 for LINELF in "${tmpary[@]}" do # ファイル名末尾の改行コードを取り除く LINE=${LINELF%?} # timestampが現在時刻のファイルは無視する \touch tmpnow if [ $LINE -ot tmpnow ]; then # 拡張子だけを得る KAKUCHOSI=${LINE##*.} if [ $KAKUCHOSI = 'ts' ] || [ $KAKUCHOSI = 'mp4' ] ; then # .mp4ファイルのコーデックがmpeg2の場合は処理対象とする if [ $KAKUCHOSI = 'mp4' ] ; then ( ${FFMPEGCMD} -i $LINE 1> /dev/null ) 2>&1 | \egrep ': Video: ' | \egrep 'mpeg2video' -q if [[ $? -ne 0 ]]; then # mpeg2でない。ループの先頭に戻り次のファイルを処理 \continue fi fi # ファイル名の最初のピリオド以下を取り除く BASETMP=${LINE%%.*} # _tss がファイル名語尾にあれば取り除く BASESTR=${BASETMP%%_tss} # 拡張子を無視したファイル名が検索先ファイルに1つだけの場合 tsファイルをmp4ファイルに変換する CNT=`\grep -c $BASESTR ${FILE2}` if [ $CNT -eq 1 ]; then N=$(($N + 1)) \ts2h264${FFMPEGCMD}.sh $LINE fi fi fi done if [ -e tmpnow ]; then \rm tmpnow fi \echo "Finished." 1>&2 \echo "$N file(s) done." 1>&2 exit 0