FFMPEG多进程转码

FFMPEG多进程转码

最近做项目,需要对linux服务器上的视频做批量转码,所以研究了下linux shell编程,通过各种途径搜寻资料,结合项目实际情况,完成了以下脚本,功能比较简单,希望对其他有相似需求的人有所帮助。

代码的主要功能为配置进程上限,并行对指定文件夹内文件进行递归,将所有非mp4格式的视频进行转码,统一转为mp4格式,同时生成缩略图


知识点归纳

  • 文件递归
  • 并发进程数量控制
  • ffmpeg命令使用
#!/bin/bash
#未解决的问题:输入的第二个参数无法获取;ok
#qsv格式视频无法转码,需要检查ffmpeg;
#转码成功的视频,放入到一个专门的文件中记录;
#转码失败的视频,放入到一个专门的文件中记录;
#转码中的视频,跳过;
function scandir() {
    local cur_dir parent_dir workdir isTransFailed
    workdir=$1
    isTransFailed=$2
    if [[ $isTransFailed = "" ]]
    then
        isTransFailed="n"
    else
        isTransFailed="y"
    fi
    cd $workdir
    if [ $workdir = "/" ]
    then
        cur_dir=""
    else
        cur_dir=$(pwd)
    fi
    for dirlist in $(ls $cur_dir)
    do
        if test -d $dirlist
        then
            cd $dirlist
            scandir $cur_dir/$dirlist $isTransFailed
            cd ..
        else    #cat /proc/sys/kernel/random/uuid
            #跳过非法格式的文件
            if [ "${dirlist##*.}" = "out" ] || [ "${dirlist##*.}" = "jpg" ] || [ "${dirlist##*.}" = "mp4" ] || [ "${dirlist##*.}" = "" ]
            then
                continue
            fi
            #如果没有对应的out文件,直接转码
            if  [ ! -f "$cur_dir/${dirlist%%.*}.mp4.out" ]
            then
                echo ${cur_dir}/${dirlist}/"开始转码》》》"
                read -u6 # 从文件描述符6中读取行(实际指向fifo管道)
                {
                    /usr/local/bin/ffmpeg -y -i ${cur_dir}/${dirlist} -vcodec libx264 -vb 450k -acodec libvo_aacenc ${cur_dir}/${dirlist%%.*}.mp4 > ${cur_dir}/${dirlist%%.*}.mp4.out 2>&1
                    echo >&6 # 再次往fifo管道文件中写入一个空行。
                } &
                echo "查看进度,请执行命令:tail -f "${cur_dir}/"\"${dirlist%%.*}.mp4.out\""
            fi
            #如果已经转过码,那么会有out文件,根据out文件判断是否需要再次转码
            local outfile="$cur_dir/${dirlist%%.*}.mp4.out"
            #转码失败,或者out文件被清空,则打印原视频文件名
            if [ $(cat $outfile|grep failed)x = "Conversion failed!"x ] || [ ! -s $outfile ]
            then
                #echo ${outfile}
                echo "文件转换失败:"$cur_dir/$dirlist
                local transErr=$(cat $outfile | awk -F ':' '/.*input.*/ {print $2}')
                echo "失败原因:"$transErr
                if [[ $isTransFailed = "y" ]]
                then
                                        echo ${cur_dir}/${dirlist}/"重新执行转码》》》"
                    read -u6 # 从文件描述符6中读取行(实际指向fifo管道)
                    {
                        /usr/local/bin/ffmpeg -y -i ${cur_dir}/${dirlist} -vcodec libx264 -vb 450k -acodec libvo_aacenc ${cur_dir}/${dirlist%%.*}.mp4 > ${cur_dir}/${dirlist%%.*}.mp4.out 2>&1
                        echo >&6 # 再次往fifo管道文件中写入一个空行。
                    } &
                                        echo "查看进进度,请执行命令:tail -f "${cur_dir}/"\"${dirlist%%.*}.mp4.out\""
                fi
            else
                #tmpt=$(cat ${cur_dir}/${dirlist} | awk -F ',' '/Input.*/ {print $3}')
                echo "文件转换成功,或者在转换中:"$cur_dir/$dirlist > /dev/null
            fi

        fi
    done
}

oldIFS=$IFS
IFS=$(echo -en "\n\b")
if test -d $1
then
    #############进程控制管道########################################################################
    SEND_THREAD_NUM=200   #设置线程数,在这里所谓的线程,其实就是几乎同时放入后台(使用&)执行的进程。
    tmp_fifofile="/tmp/$$.fifo" # 脚本运行的当前进程ID号作为文件名
    mkfifo "$tmp_fifofile" # 新建一个随机fifo管道文件
    exec 6<>"$tmp_fifofile" # 定义文件描述符6指向这个fifo管道文件
    for ((i=0;i<$SEND_THREAD_NUM;i++));do
        echo >&6 # for循环 往 fifo管道文件中写入SEND_THREAD_NUM个空行
    done 
    ###########开始执行转码
    scandir $1 $2
    ###########等待转换结束
    wait 
    rm "$tmp_fifofile"
elif test -f $1
then
    echo "you input a file but not a directory,pls reinput and try again"
    exit 1
else
    echo "the Directory isn't exist which you input,pls input a new one!!"
    exit 1
fi
IFS=$oldIFS
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Python中使用FFmpeg进行多进程分割视频文件可以通过以下步骤实现: 1. 首先,你需要安装FFmpeg并确保它已经添加到系统的环境变量中。你可以从FFmpeg的官方网站(https://ffmpeg.org/)下载并安装它。 2. 在Python中,你可以使用`subprocess`模块来执行FFmpeg命令。首先,导入`subprocess`模块: ```python import subprocess ``` 3. 接下来,你可以使用`subprocess.Popen`函数来启动一个新的进程并执行FFmpeg命令。例如,你可以使用以下代码来分割视频文件: ```python def split_video(input_file, output_file, start_time, duration): command = ['ffmpeg', '-i', input_file, '-ss', start_time, '-t', duration, '-c', 'copy', output_file] process = subprocess.Popen(command) process.wait() ``` 在上面的代码中,`input_file`是输入视频文件的路径,`output_file`是输出视频文件的路径,`start_time`是分割开始的时间(以秒为单位),`duration`是分割的持续时间(以秒为单位)。 4. 如果你想要同时分割多个视频文件,你可以使用Python的多进程库(如`multiprocessing`)来实现并行处理。以下是一个示例代码: ```python import multiprocessing def split_video(input_file, output_file, start_time, duration): # 分割视频的代码 if __name__ == '__main__': input_files = ['video1.mp4', 'video2.mp4', 'video3.mp4'] output_files = ['output1.mp4', 'output2.mp4', 'output3.mp4'] start_times = [10, 20, 30] durations = [5, 10, 15] processes = [] for i in range(len(input_files)): process = multiprocessing.Process(target=split_video, args=(input_files[i], output_files[i], start_times[i], durations[i])) processes.append(process) process.start() for process in processes: process.join() ``` 在上面的代码中,`input_files`是输入视频文件的路径列表,`output_files`是输出视频文件的路径列表,`start_times`是分割开始的时间列表,`durations`是分割的持续时间列表。通过循环创建多个进程来同时处理多个视频文件的分割操作。 这样,你就可以使用FFmpeg和Python的多进程库来实现多进程分割视频文件了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值