| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- #!/bin/bash
- Media="$1"
- ForceH264="${2:-0}"
- Uploader="upload.sh"
- M3u8mod="m3u8.sh"
- Publish="publish.sh"
- BitRadio="1.55"
- ForceBitRadio="1.75"
- ForceMaxRadio="1.20"
- ForceRate="2400000"
- MaxSize=5
- MaxCheck=10
- MaxTime=10
- AutoClear=0
- QuickMode=1
- # Main
- if [ -n "${Media}" ] && [ -f "${Media}" ]; then
- echo "$ForceH264" |grep -q "^-"
- [ "$?" -eq 0 ] && QuickMode=0
- ForceH264=`echo "$ForceH264" |grep -o "[0-9]\{1,\}"`
- [ -n "$ForceH264" ] || ForceH264=0
- echo "media file: '${Media}'."
- else
- [ -n "${Media}" ] && echo "Not found '${Media}'." || echo "Please input a media file."
- exit 1
- fi
- MediaName=`basename "${Media}" |cut -d'.' -f1 |sed 's/[[:space:]]/_/g'`
- ScriptDir=`dirname $0`
- CurrentDir=`pwd`
- OutPutM3u8="${CurrentDir}/${MediaName}.m3u8"
- OutPutM3u8Bak="${CurrentDir}/${MediaName}.m3u8.bak"
- OutPutLog="${CurrentDir}/${MediaName}.log"
- MediaFolder="${CurrentDir}/${MediaName}.output"
- # cache
- [ "$QuickMode" == 1 ] && [ -f "${OutPutM3u8Bak}" ] && [ -d "${MediaFolder}" ] || QuickMode=0
- if [ "$QuickMode" != 1 ]; then
- rm -rf "${OutPutLog}"
- rm -rf "${MediaFolder}"
- mkdir -p "${MediaFolder}"
- else
- rm -rf "${OutPutLog}"
- fi
- ## m3u8
- if [ "$QuickMode" != 1 ]; then
- BitRate=`ffprobe -v error -show_entries format=bit_rate -of default=noprint_wrappers=1:nokey=1 "${Media}"`
- echo "media bitrate: ${BitRate}"
- if [ "$ForceH264" -eq 0 ]; then
- _ForceH264=`awk 'BEGIN{print '${BitRate}' / ('${ForceBitRadio}' * '${ForceRate}')}' |cut -d'.' -f1`
- [ "$_ForceH264" -ne 0 ] && ForceH264=1
- fi
- if [ "$ForceH264" -ge 2 ]; then
- MediaCode=`ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 "${Media}" |sort |uniq`
- if [ "$MediaCode" != "h264" ]; then
- echo "Error: This media file code '${MediaCode}', must 'h264' in this mode."
- exit 1
- fi
- VideoCode="copy"
- VideoAddon="-bsf:v h264_mp4toannexb"
- [ "$ForceH264" -le 2 ] && VideoTime="2" || VideoTime="$ForceH264"
- elif [ "$ForceH264" -eq 1 ]; then
- ForceMaxRate=`awk 'BEGIN{print '${ForceRate}' * '${ForceMaxRadio}'}' |cut -d'.' -f1`
- ForceBuf=`awk 'BEGIN{print '${ForceRate}' / '${ForceMaxRadio}'}' |cut -d'.' -f1`
- VideoAddon="-b:v ${ForceRate} -maxrate ${ForceMaxRate} -bufsize ${ForceBuf}"
- VideoCode="h264"
- if [ "$BitRate" -gt "3500000" ]; then
- BitRadio="${ForceBitRadio}"
- fi
- BitRate=3000000
- echo "media bitrate(new): ${BitRate}"
- else
- MediaCode=`ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 "${Media}" |sort |uniq`
- if [ "$MediaCode" == "h264" ]; then
- VideoCode="copy"
- else
- VideoCode="h264"
- fi
- if [ "$VideoCode" == "copy" ]; then
- VideoAddon="-bsf:v h264_mp4toannexb"
- else
- if [ "$BitRate" -gt "3500000" ]; then
- BitRadio="${ForceBitRadio}"
- BitRate=3000000
- else
- ForceRate="${BitRate}"
- BitRate=`awk 'BEGIN{print '${ForceRate}' * '${ForceBitRadio}'}' |cut -d'.' -f1`
- fi
- echo "media bitrate(new): ${BitRate}"
- ForceMaxRate=`awk 'BEGIN{print '${ForceRate}' * '${ForceMaxRadio}'}' |cut -d'.' -f1`
- ForceBuf=`awk 'BEGIN{print '${ForceRate}' / '${ForceMaxRadio}'}' |cut -d'.' -f1`
- VideoAddon="-b:v ${ForceRate} -maxrate ${ForceMaxRate} -bufsize ${ForceBuf}"
- fi
- fi
- if [ "$ForceH264" -le 1 ]; then
- VideoTime=`awk 'BEGIN{print ('${MaxSize}' * 1024 * 1024 * 8) / ('${BitRate}' * '${BitRadio}') }' |cut -d'.' -f1`
- if [ -n "$VideoTime" ]; then
- if [ "${BitRate}" -gt 3500000 ]; then
- MaxTime=5
- elif [ "${BitRate}" -gt 3000000 ]; then
- MaxTime=7
- fi
- if [ "$VideoTime" -gt "$MaxTime" ]; then
- VideoTime="$MaxTime"
- fi
- else
- exit 1
- fi
- fi
- echo "media segment time: ${VideoTime}"
- ffmpeg -v info -i "${Media}" -vcodec ${VideoCode} -acodec aac -strict experimental ${VideoAddon} -map 0:v:0 -map 0:a? -f segment -segment_list "${OutPutM3u8}" -segment_time "${VideoTime}" "${MediaFolder}/output_%04d.ts"
- if [ $? -ne 0 ]; then
- exit 1
- else
- cp -rf "${OutPutM3u8}" "${OutPutM3u8Bak}"
- fi
- else
- cp -rf "${OutPutM3u8Bak}" "${OutPutM3u8}"
- fi
- ## upload
- echo "start upload..."
- if [ -e "${ScriptDir}/${Uploader}" ]; then
- bash "${ScriptDir}/${Uploader}" "${MediaFolder}" |tee -a "${OutPutLog}"
- ## mod m3u8
- if [ -f "${ScriptDir}/${M3u8mod}" ]; then
- bash "${ScriptDir}/${M3u8mod}" "${OutPutLog}" "${OutPutM3u8}"
- fi
- fi
- # check
- echo "check upload..."
- function ForceVBR(){
- fsName="$1"
- loopTimes="$2"
- [ -n "${fsName}" ] && [ -f "${fsName}" ] || return
- [ `du -s -k "${fsName}" |cut -f1` -le `awk 'BEGIN{print '${MaxSize}' * 1024}' |cut -d'.' -f1` ] && return
- NewFsName="${fsName}_New.ts"
- cp -rf "${fsName}" "${NewFsName}"
- LowerRadio=`awk 'BEGIN{print 0.85 ** '${loopTimes}'}'`
- NewForceRate=`awk 'BEGIN{print '${ForceRate}' * '${LowerRadio}'}' |cut -d'.' -f1`
- NewForceMaxRate=`awk 'BEGIN{print '${NewForceRate}' * '${ForceMaxRadio}'}' |cut -d'.' -f1`
- NewForceBuf=`awk 'BEGIN{print '${NewForceRate}' / '${ForceMaxRadio}'}' |cut -d'.' -f1`
- VideoAddon="-b:v ${NewForceRate} -maxrate ${NewForceMaxRate} -bufsize ${NewForceBuf}"
- ffmpeg -y -v info -i "${NewFsName}" -copyts -vsync 0 -muxdelay 0 -vcodec h264 -acodec copy -strict experimental -bsf:v h264_mp4toannexb ${VideoAddon} -f mpegts "${fsName}"
- [ -f "${NewFsName}" ] && [ -f "${fsName}" ] && rm -rf "${NewFsName}"
- }
- for((i=0; i<$MaxCheck; i++)); do
- BadCheck=`grep -v "^#\|^https\?://" "${OutPutM3u8}"`
- [ -n "$BadCheck" ] || break
- for Item in `echo "$BadCheck"`; do
- if [ -f "${Item}" ]; then
- BadItem="${Item}"
- elif [ -f "${MediaFolder}/${Item}" ]; then
- BadItem="${MediaFolder}/${Item}"
- else
- echo "Error: not found '${Item}'."
- exit 1
- fi
- ForceVBR "${BadItem}" "${i}"
- bash "${ScriptDir}/${Uploader}" "${BadItem}" |tee -a "${OutPutLog}"
- done
- sed -i '/;\ NULL_/d' "${OutPutLog}"
- ## mod m3u8
- if [ -f "${ScriptDir}/${M3u8mod}" ]; then
- bash "${ScriptDir}/${M3u8mod}" "${OutPutLog}" "${OutPutM3u8}"
- fi
- done
- # publish
- if [ -f "${ScriptDir}/${Publish}" ]; then
- echo "publish ..."
- bash "${ScriptDir}/${Publish}" "${OutPutM3u8}"
- fi
- # clear
- if [ "$AutoClear" != 0 ]; then
- rm -rf "${OutPutLog}"
- rm -rf "${MediaFolder}"
- rm -rf "${OutPutM3u8Bak}"
- fi
|