ffmpeg使用命令

视频更改格式

ffmpeg -i input.mp4 output.avi
原视频格式有问题的,如时间戳问题,想要重新进行编码:
ffmpeg -i input.wav -c copy 0.wav
使用-fflags +igndts参数。该参数告诉ffmpeg忽略不连续的时间戳。这个选项可以用来修复一些由于不连续 DTS 导致的问题。
ffmpeg -f concat -safe 0 -i file.txt -c copy -fflags +igndts output.wav -y

判断视频的帧速率

ffprobe -v quiet -select_streams v -of csv=p=0 -show_entries stream=r_frame_rate input_path

调整视频的帧速率

ffmpeg -i input_path -vf “fps=30” -strict -2 output_path

获取视频的时长

ffmpeg -i input_path 2>&1 | grep “Duration”

截取任意一帧图像

ffmpeg -i 1.mp4 sample.jpg -ss 00:00:01 -vframes 1 -an -vcodec mjpeg

将音视频按照特定时长来进行拆分

ffmpeg -i input_path -ss start_time -t end_time output_path -y
ffmpeg -i input_path -strict -2 -ss start_time -t end_time output_path -y

视频倒放命令

ffmpeg -i input.mp4 -vf reverse -af areverse -preset superfast output.mp4

音频文件和视频文件的拼接

ffmpeg -i <video_file> -i <audio_file> -c:v copy -c:a aac -strict experimental <output_file>

两个视频文件拼接

ffmpeg -i 1.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb 1.ts
ffmpeg -i 2.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb 2.ts
ffmpeg -i “concat:1.ts|2.ts” -acodec copy -vcodec copy -absf aac_adtstoasc output.mp4

多视频文件拼接

#  便利文件夹下的要拼接的视频文件
def file_exists(train_input_folder):
    if os.path.exists(train_input_folder):
        #  遍历该路径下所有文件名
        files = os.listdir(train_input_folder)
        if len(files) > 0:
            return files
        else:
            logger.debug(f'(推理音频)文件路径错误,{
      
      train_input_folder}该路径为空文件夹!')
            return None
    else:
        logger.debug(f'(推理音频)文件路径错误,{
      
      train_input_folder}该路径不存在!')
        return None
#  多视频拼接
def videos_join(output_folder):
    #  输出路径
    # output_folder = '/home/bmxm/news_bilibili'
    files = file_exists(output_folder)
    if files is not None:
        if files[0].endswith(".mp4"):
            mp4_files = [file for file in files if file.endswith(".mp4")]
            #  拼接视频(创建TXT、视频拼接命令)
            cmd = ""
            for p in mp4_files:
                cmd += r"echo file \''{}/{}'\' >> file.txt ;".format(output_folder, p)
            os.system(cmd)
            cmd = 'ffmpeg -f concat -safe 0 -i file.txt -y ' + output_folder + '/output.mp4'
            os.system(cmd)
            cmd = 'rm -f file.txt'
            os.system(cmd)
            return output_folder + '/output.mp4'
        elif files[0].endswith(".wav"):
            mp4_files = [file for file in files if file.endswith(".wav")]
            #  拼接音频(创建TXT、视频拼接命令)
            cmd = ""
            for p in mp4_files:
                cmd += r"echo file \''{}/{}'\' >> file.txt ;".format(output_folder, p)
            os.system(cmd)
            cmd = 'ffmpeg -f concat -safe 0 -i file.txt -y ' + output_folder + '/output.wav'
            os.system(cmd)
            cmd = 'rm -f file.txt'
            os.system(cmd)
            return output_folder + '/output.wav'
    else:
        return f'{
      
      output_folder} 文件路径为空!!'

其他ffmpeg命令:

财经新闻的新闻介绍每隔一段时间出现一次

图片插入到视频中

ffmpeg -i video.mp4 -i image.png -filter_complex "[0:v][1:v] overlay=25:25:enable='between(t,0,20)'" -pix_fmt yuv420p -c:a copy output.mp4
ffmpeg -i video.mp4 -i image.png -filter_complex "[1:v]scale=320:-1[img]; [0:v][img] overlay=50:400:enable='between(t,0,6)+between(t,20,30)'" -pix_fmt yuv420p -c:a copy output.mp4

-filter_complex是过滤器,overlay=25:25是图片的坐标位置,enable='between(t,0,6)+between(t,20,30)'是图片在第0秒开始展示6秒,再从第20秒展示到30秒
在这里插入图片描述

字幕效果

ffmpeg -i input.mp4 -vf "subtitles=subtitles.srt" output.mp4
ffmpeg -i caijing.mp4 -vf "drawtext=text=两个人又把小男孩抱走了,同样把他扔到那条河里去,而这个时候那只小鸟又来了,它在空中飞着,边飞边唱。你要死了,远远地告诉百合花,好男孩,是你吗?告诉百合花。:fontfile=Microsoft YaHei Mono.ttf:y=h-line_h-10:x=w-(t-0.5)*w/3:fontcolor=white:fontsize=36:shadowx=2:shadowy=2" output.mp4

画中画显示

#  画中画显示  scale=w=200:-1中"-2"对高度进行调整,会让计算出的高度总是偶数
ffmpeg -i target_video.mp4 -i insert_video.mp4 -filter_complex "[1:v]scale=w=200:-1[insert];[0:v][insert]overlay=x=10:y=10" -codec:a copy output_video.mp4
ffmpeg -i 30rate_1.mp4 -i caijin_ffm.mp4 -filter_complex "[1:v]scale=w=200:-2[insert];[0:v][insert]overlay=x=10:y=10" -codec:a copy output_video.mp4

查看视频、图片尺寸

def video_size(input_path):
    cmd = 'ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 ' + input_path
    result = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    output = result.communicate()[0].decode('utf-8')
    logger.debug(f'{
      
      input_path}视频尺寸为:{
      
      output}')
    return output


def pic_size(pic_path):
    cmd = 'ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=p=0 ' + pic_path
    result = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    output = result.communicate()[0].decode('utf-8')
    logger.debug(f'{
      
      pic_path}图片尺寸为:{
      
      output}')
    return output

视频绿幕背景变透明背景(最后输出格式为:webm)本地查看为绿色,浏览器中查看为透明背景

cmd = 'ffmpeg -i ' + input_path + ' -vf "chromakey=0x00FF00:0.25:0.1" -c copy -c:v png ' + mid_file + ' -y'
cmd = 'ffmpeg -y -i ' + mid_file + ' -vf "chromakey=0x00FF00:0.25:0.1" -c copy -c:v libvpx-vp9 -c:a libopus ' + output_path

将webm格式的透明背景视频,转换成指定背景的视频

#  将webm格式的透明背景视频,转换成指定背景的视频
def background(data):
    #  此input_path文件为:bbb.webm
    input_path = data.get('input_path', '')
    pic_path = data.get('pic_path', '')
    username = data.get('username', '')
    modelname = data.get('modelname', '')
    timestamp = data.get('timestamp', '')
    if username and modelname and timestamp and pic_path:
        output_folder = '/home/bmxm/FFmpeg_134/background/' + username + '/' + modelname + '/' + str(timestamp)
        cmd = 'mkdir -p ' + output_folder
        os.system(cmd)
        output_path = os.path.join(output_folder, '/output.mp4')
        #  查看视频尺寸
        video = video_size(input_path)
        video_width = str(video).split('x')[0]
        video_height = str(video).split('x')[1]
        pic = pic_size(pic_path)
        pic_width = str(pic).split(',')[0]
        pic_height = str(pic).split(',')[1]
        #  对比图片尺寸和视频尺寸
        if pic_width < video_width or pic_height < video_height:
            return f'图片尺寸{
      
      pic}小于视频尺寸{
      
      video},无法进行裁剪!'
        else:
            filename = pic_path.split("/")[-1]
            name = int(time.time())
            new_filename = str(name) + "." + filename.split(".")[-1]  # 在时间戳和后缀名之间添加点号
            pic_new_path = pic_path.replace(filename, new_filename)
            #  对图片按视频尺寸进行裁剪
            cmd = f'ffmpeg -i {
      
      pic_path} -vf "crop={
      
      video_width}:{
      
      video_height}" {
      
      pic_new_path}'
            os.system(cmd)
            #  执行绿幕换背景命令
            path = str(pic_new_path).replace(str(pic_new_path).split('/')[-1].split('.')[0], str(timestamp))
            cmd = 'convert -blur 0x8 ' + pic_new_path + ' ' + path
            os.system(cmd)
            cmd = 'ffmpeg -c:v libvpx-vp9 -i ' + input_path + ' -i ' + path + ''' -filter_complex "[1:v][0:v] 
            overlay=25:25:enable='between(t,0,20)'" -pix_fmt yuv420p -c:a copy ''' + output_path
            os.system(cmd)
            return output_path + '/output.mp4'


def cut_video(data):
    input_path = data.get('input_path', '')
    width = data.get('width', '')
    height = data.get('height', '')
    x = data.get('x', '')
    y = data.get('y', '')
    username = data.get('username', '')
    modelname = data.get('modelname', '')
    timestamp = data.get('timestamp', '')
    if width and height and x and y:
        output_folder = '/home/bmxm/FFmpeg_134/cut_video/' + username + '/' + modelname + '/' + str(timestamp)
        # 构建输出文件的完整路径
        output_path = os.path.join(output_folder, '/output.mp4')
        cmd = 'mkdir -p ' + output_folder
        os.system(cmd)
        # 视频截取功能
        cmd = 'ffmpeg -i {0} -filter:v "crop={1}:{2}:{3}:{4}" {5}'.format(input_path, width, height, x, y, output_path)
        exit_code = os.system(cmd)
        if exit_code == 0:
            logger.debug(f'{
      
      input_path}视频裁剪成功!截取尺寸:{
      
      width}{
      
      height},坐标:{
      
      x}{
      
      y}')
            return output_path + '/output.mp4'
    else:
        logger.debug('指定参数不能为空。(截取尺寸width、height,坐标:x、y)')
        return '指定参数不能为空。(截取尺寸width、height,坐标:x、y)'

猜你喜欢

转载自blog.csdn.net/douliyoufeng/article/details/132041972