• python+ffmpeg切割视频


    什么是ffmpeg

    1.1 简介

    FFmpeg是一个开源免费跨平台的视频和音频流方案,属于自由软件,采用LGPL或GPL许可证(依据你选择的组件)。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多codec都是从头开发的。

    FFmpeg提供了强大的命令行工具,非常方便用户使用以及二次开发。

    官方网站:http://ffmpeg.org/

    1.2 组件

    FFmpeg项目由以下几部分组成:

    1.FFmpeg视频文件转换命令行工具,也支持经过实时电视卡抓取和编码成视频文件;

    2.ffserver基于HTTP、RTSP用于实时广播的多媒体服务器.也支持时间平移;

    3.ffplay用 SDL和FFmpeg库开发的一个简单的媒体播放器;

    4.libavcodec一个包含了所有FFmpeg音视频编解码器的库。为了保证最优性能和高可复用性,大多数编解码器从头开发的;

    5.libavformat一个包含了所有的普通音视格式的解析器和产生器的库。

    安装

    下载免编译版本:xxxx-static.tar.gz 版本中包含static是免编译版本,

    免编译版本下载地址:https://johnvansickle.com/ffmpeg/

    安装步骤如下:

     1 $ cd /home/john
     2 $ wget https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-64bit-static.tar.xz
     3 $ wget https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-64bit-static.tar.xz.md5
     4 $ md5sum -c ffmpeg-git-64bit-static.tar.xz.md5
     5 ffmpeg-git-64bit-static.tar.xz: OK
     6 $ xz -d ffmpeg-git-64bit-static.tar.xz
     7 $ tar -cvf ffmpeg-git-64bit-static.tar
     8 $ ls ffmpeg-git-20180203-64bit-static
     9 ffmpeg  ffmpeg-10bit  ffprobe  GPLv3.txt  manpages  model  qt-faststart  readme.txt
    10 $ pwd
    11 /home/john
    12 
    13 $ ./ffmpeg-git-20180203-64bit-static/ffmpeg
    14 ffmpeg version N-89948-ge3d946b3f4-static https://johnvansickle.com/ffmpeg/  Copyright (c) 2000-2018 the FFmpeg developers
    15   built with gcc 6.4.0 (Debian 6.4.0-11) 20171206
    16 (snipped output to save space)

     常用的集合选项

    –y表示覆盖输出文件;
    
    –i表示输入文件;
    -t duration 设置纪录时间 hh:mm:ss[.xxx]格式的记录时间也支持
    -ss position 搜索到指定的时间 [-]hh:mm:ss[.xxx]的格式也支持

    其他更加详细以及高级用法参考

    https://wuyuans.com/2011/11/ffmpeg-syntax

    剪切视频

      ./ffmpeg -ss 00:00:06 -t 00:00:12 -i input.mp4 -vcodec copy -acodec copy output.mp4

    批量处理视频

    由于视频很大,我想切割成一个一个小的视频文件保存起来

    脚本如下

     1 #!/usr/local/src/Python-2.7.15/python
     2 import string
     3 
     4 import os 
     5 import time
     6 import re
     7 import math
     8 import sys
     9 from optparse import OptionParser
    10 
    11 print "Test by zzz start..."
    12 parser = OptionParser()
    13 parser.add_option("-i", "--input", dest="input",action="store_true",help="input x y for each file by user")
    14 parser.add_option("-q", "--quality", dest="q",action="store",help="input xvid q arg",default="24")
    15 parser.add_option("-v", "--vcodec", dest="vcodec",action="store",help="input video codec",default="x264")
    16 parser.add_option("-n", "--noaudio", dest="an",action="store_true",help="no audio")
    17 parser.add_option("-p", "--preset", dest="preset",action="store",help="",default="")
    18 parser.add_option("-m", "--maxWidth", dest="maxWidth",action="store",help="input max width for output video",default="")
    19 parser.add_option("-f", "--fileType", dest="fileType",action="store",help="",default="mp4")
    20 parser.add_option("-o", "--ogg", dest="ogg",action="store_true",help="user ogg instead of aac",default="")
    21 parser.add_option("-3", "--mp3", dest="mp3",action="store_true",help="user mp3 instead of aac",default="")
    22 parser.add_option("-1", "--pad", dest="pad",action="store_true",help="pad to 16:9",default="")
    23 parser.add_option("-s", "--src", dest="srcD",action="store",help="source dir",default="/usr/local/src/test/videoin")
    24 parser.add_option("-t", "--target", dest="targetD",action="store",help="target dir",default="/usr/local/src/test/videoout")
    25 parser.add_option("-w", "--workdir", dest="workdir",action="store",help="work dir",default="/usr/local/src/test/video")
    26 parser.add_option("-e", "--split", dest="split",action="store_true",help="split to multiple file with size")
    27 parser.add_option("-d", "--splitsize", dest="splitsize",action="store",help="split to multiple file with size",default="2")#Minutes
    28 parser.add_option("-j", "--prefix", dest="prefix",action="store",help="target file name prefix",default="")
    29 
    30 (options, args) = parser.parse_args()
    31 
    32 if options.srcD==None or options.srcD[0:1]=='-':
    33     print 'srcD Err, quit'
    34     exit() 
    35 if options.targetD==None or options.targetD[0:1]=='-':
    36     print 'targetD Err, quit'
    37     exit() 
    38 if options.fileType==None or options.fileType[0:1]=='-':
    39     print 'fileType Err, quit'
    40     exit() 
    41 if options.workdir==None or options.workdir[0:1]=='-':
    42     print 'workdir Err, quit'
    43     exit() 
    44     
    45 #获取视频文件的名字
    46 for root,dirs,files in os.walk(options.srcD): 
    47     for name in files:
    48         name= name.replace('[','''[''')#??????[????
    49         newname =name[0: name.rindex('.')]      
    50         print "Test newname: " + newname
    51         print "Test name: " + name
    52 
    53         
    54         
    55 #??
    56         cmd ='cd '+options.workdir+';mkdir -p ffm;  rm -f ffm/ffm.txt ; sh -c "(/usr/local/src/ffmpeg-git-20181015-64bit-static/ffmpeg -i '+options.srcD+'/' +name+ ' >& ffm/ffm.txt)"; grep Duration ffm/ffm.txt'
    57         #ffmpeg -i  xxx.mp4  能够得到视频文件的时间信息
    58         print cmd
    59         (si, so, se) = os.popen3(cmd)
    60         t=so.readlines()  ##['  Duration: 00:26:52.92, start: 0.000000, bitrate: 248 kb/s
    ']
    61         print t 
    62         reg='''Duration:s(d+):(d+):([d.]+)'''
    63         duration=0#second
    64         for line in t:
    65             result = re.compile(reg).findall(line)##result=[('00', '26', '52.92')]
    66             for c in result:
    67                 print 'split file to',options.splitsize,'minutes, Duration:',c[0],c[1],c[2]
    68                 duration = int(c[0])*3600 + int(c[1])*60+float(c[2])##获取视频全部时间s
    69                 nameLength=int(math.log(int(duration / (int(options.splitsize)*60)) )/math.log(10)) + 1
    70                 print nameLength
    71                 for i in range(int(duration / (int(options.splitsize)*60)) + 1):##获取总计能够截取几份
    72                     print i
    73                     _t = ''
    74                     if duration>int(options.splitsize)*60*(i+1): ##当总时间数大于截取时间数时的取值
    75                         _t = str(int(options.splitsize)*60)
    76                     else:
    77                         _t = str(duration-int(options.splitsize)*60*i)
    78                         ##当总时间数小于截取时间数时的取值也就是最后一段视频
    79                     cmd ='sh -c "' + "cd "+options.workdir+";touch ffm/output.log;(/usr/local/src/ffmpeg-git-20181015-64bit-static/ffmpeg -y -i "+options.srcD+"/"+name+" -codec: copy -ss "+str(i*int(options.splitsize)*60)+" -t "+_t+" "+options.targetD+"/"+options.prefix+newname+'_'+string.replace(('%'+str(nameLength)+'s')%str(i),' ','0')+"."+options.fileType + ' >& ffm/output.log)"'
    80                     print cmd
    81                     (si, so, se) = os.popen3(cmd)
    82                     for line in se.readlines() :#????
    83                         print line
    View Code

    最后截取视频如下,每个视频两分钟:

    [root@localhost videoout]# ls -l
    total 47620
    -rw-r--r--. 1 root root 6626325 Oct 27 16:11 02_xxx.ev4_00.mp4
    -rw-r--r--. 1 root root 2551943 Oct 27 16:11 02_xxx.ev4_01.mp4
    -rw-r--r--. 1 root root 3904819 Oct 27 16:11 02_xxx.ev4_02.mp4
    -rw-r--r--. 1 root root 3380509 Oct 27 16:11 02_xxx.ev4_03.mp4
    -rw-r--r--. 1 root root 3223771 Oct 27 16:11 02_xxx.ev4_04.mp4
    -rw-r--r--. 1 root root 3004679 Oct 27 16:11 02_xxx.ev4_05.mp4
    -rw-r--r--. 1 root root 3550070 Oct 27 16:11 02_xxx.ev4_06.mp4
    -rw-r--r--. 1 root root 3362422 Oct 27 16:11 02_xxx.ev4_07.mp4
    -rw-r--r--. 1 root root 3365144 Oct 27 16:11 02_xxx.ev4_08.mp4
    -rw-r--r--. 1 root root 3301078 Oct 27 16:11 02_xxx.ev4_09.mp4
    -rw-r--r--. 1 root root 3485420 Oct 27 16:11 02_xxx.ev4_10.mp4
    -rw-r--r--. 1 root root 3468156 Oct 27 16:11 02_xxx.ev4_11.mp4
    -rw-r--r--. 1 root root 3588643 Oct 27 16:11 02_xxx.ev4_12.mp4
    -rw-r--r--. 1 root root 1922392 Oct 27 16:11 02_xxx.ev4_13.mp4

    常见的一些问题:

    -ss 放在-i前后的问题

    https://wuyuans.com/2012/04/ffmpeg-split

    一些其他用法:

    参考:http://blog.51cto.com/yuanhuan/1246370

    https://www.jianshu.com/p/2975f4efd808

     补充,由于py2.7以及py3以上popen已经废弃,使用subprocess来替代,这里改写了下脚本

     1 #!/usr/local/src/Python-2.7.15/python
     2 import string
     3 
     4 import os 
     5 import time
     6 import re
     7 import math
     8 import sys
     9 from optparse import OptionParser
    10 import subprocess
    11 print "Test by gongjia start..."
    12 
    13 
    14 parser = OptionParser()
    15 parser.add_option("-i", "--input", dest="input",action="store_true",help="input x y for each file by user")
    16 parser.add_option("-q", "--quality", dest="q",action="store",help="input xvid q arg",default="24")
    17 parser.add_option("-v", "--vcodec", dest="vcodec",action="store",help="input video codec",default="x264")
    18 parser.add_option("-n", "--noaudio", dest="an",action="store_true",help="no audio")
    19 parser.add_option("-p", "--preset", dest="preset",action="store",help="",default="")
    20 parser.add_option("-m", "--maxWidth", dest="maxWidth",action="store",help="input max width for output video",default="")
    21 parser.add_option("-f", "--fileType", dest="fileType",action="store",help="",default="mp4")
    22 parser.add_option("-o", "--ogg", dest="ogg",action="store_true",help="user ogg instead of aac",default="")
    23 parser.add_option("-3", "--mp3", dest="mp3",action="store_true",help="user mp3 instead of aac",default="")
    24 parser.add_option("-1", "--pad", dest="pad",action="store_true",help="pad to 16:9",default="")
    25 parser.add_option("-s", "--src", dest="srcD",action="store",help="source dir",default="/usr/local/src/test/videoin")
    26 parser.add_option("-t", "--target", dest="targetD",action="store",help="target dir",default="/usr/local/src/test/videoout")
    27 parser.add_option("-w", "--workdir", dest="workdir",action="store",help="work dir",default="/usr/local/src/test/video")
    28 parser.add_option("-e", "--split", dest="split",action="store_true",help="split to multiple file with size")
    29 parser.add_option("-d", "--splitsize", dest="splitsize",action="store",help="split to multiple file with size",default="2")#Minutes
    30 parser.add_option("-j", "--prefix", dest="prefix",action="store",help="target file name prefix",default="")
    31 
    32 (options, args) = parser.parse_args()
    33 
    34 if options.srcD==None or options.srcD[0:1]=='-':
    35     print 'srcD Err, quit'
    36     exit() 
    37 if options.targetD==None or options.targetD[0:1]=='-':
    38     print 'targetD Err, quit'
    39     exit() 
    40 if options.fileType==None or options.fileType[0:1]=='-':
    41     print 'fileType Err, quit'
    42     exit() 
    43 if options.workdir==None or options.workdir[0:1]=='-':
    44     print 'workdir Err, quit'
    45     exit() 
    46     
    47 #??videoin????
    48 for root,dirs,files in os.walk(options.srcD): 
    49     for name in files:
    50         name= name.replace('[','''[''')#??????[????
    51         newname =name[0: name.rindex('.')]      
    52         print "Test newname: " + newname
    53         print "Test name: " + name
    54         os.chdir(options.workdir)
    55         cmd ='mkdir -p ffm;rm -f ffm/ffm.txt;/usr/local/src/ffmpeg-git-20181015-64bit-static/ffmpeg -i '+options.srcD+'/' +name+ ' >& ffm/ffm.txt;pwd'
    56         cmd1=['grep','Duration','ffm/ffm.txt']
    57         for i in cmd.split(';'):
    58             print i
    59             time.sleep(3)
    60             t1=subprocess.Popen(i,shell=True)
    61         obj=subprocess.Popen(cmd1, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    62         (s1,s2)=obj.communicate()
    63         print s1
    64         reg='''Duration:s(d+):(d+):([d.]+)'''
    65         result = re.compile(reg).findall(s1)
    66         print result
    67         for c in result:
    68             print 'split file to',options.splitsize,'minutes, Duration:',c[0],c[1],c[2]
    69             duration = int(c[0])*3600 + int(c[1])*60+float(c[2])##????????s
    70             nameLength=int(math.log(int(duration / (int(options.splitsize)*60)) )/math.log(10)) + 1
    71             print nameLength
    72             for i in range(int(duration / (int(options.splitsize)*60)) + 1):##??????????
    73                 print i
    74                 if duration>int(options.splitsize)*60*(i+1):
    75                     _t = str(int(options.splitsize)*60)
    76                 else:
    77                     _t = str(duration-int(options.splitsize)*60*i)
    78                 os.chdir(options.workdir)
    79                 cmd = "touch ffm/output.log;/usr/local/src/ffmpeg-git-20181015-64bit-static/ffmpeg -y -i "+options.srcD+"/"+name+" -codec: copy -ss "+str(i*int(options.splitsize)*60)+" -t "+_t+" "+options.targetD+"/"+options.prefix+newname+'_'+string.replace(('%'+str(nameLength)+'s')%str(i),' ','0')+"."+options.fileType + ' >& ffm/output.log'
    80                 for i in cmd.split(';'):
    81                     print i
    82                     time.sleep(2)
    83                     t1=subprocess.Popen(i,shell=True)
    84                     print t1
    85                     
    86 time.sleep(3)
    View Code
  • 相关阅读:
    第十四周 Leetcode 315. Count of Smaller Numbers After Self(HARD) 主席树
    POJ1050 To the Max 最大子矩阵
    POJ1259 The Picnic 最大空凸包问题 DP
    POJ 3734 Blocks 矩阵递推
    POJ2686 Traveling by Stagecoach 状态压缩DP
    iOS上架ipa上传问题那些事
    深入浅出iOS事件机制
    iOS如何跳到系统设置里的各种设置界面
    坑爹的私有API
    业务层网络请求封装
  • 原文地址:https://www.cnblogs.com/Dicky-Zhang/p/9867391.html
Copyright © 2020-2023  润新知