Package: ffmpeg-generator
FFmpeg GeneratorA FFmpeg command generator and actuator.Python bindings for FFmpeg - with almost all filters support, evengltransitionfilter.FFmpeg GeneratorOverviewTODOInstallationDocumentsGLTransition FilterVideo SourcesPlay by FFplayPreview by FFmpegSave Video from video sourcesMore ExamplesGet Stream InfoPlay a VideoGenerate Thumbnail for VideoConvert Video to Numpy ArrayRead Single Video Frame as JPEGConvert Sound to Raw PCM AudioAssemble Video from Sequence of FramesAudio/Video PipelineMono to Stereo with Offsets and VideoProcess FramesFaceTime Webcam InputStream from a Local Video to HTTP ServerStream from RTSP Server to TCP SocketSpecial ThanksOverviewThis project is based onffmpeg-python. But rewrite all.support video sourcessupport almost all filterssupport FFplay&FFprobeenable cuda hwaccel by default, or close globally by code belowfromffmpegimportsettingssettings.CUDA_ENABLE=FalseInstallationpipinstall-Uffmpeg-generatorDocumentsFFmpeg comes with more than 450 audio and video media filters.
It is recommended to read the official documentation.FFmpeg HomepageFFmpeg DocumentationFFmpeg Filters DocumentationOr read my study notes, plan to demonstrate all the filters, but written in Chinese. Not all done yet.All Examples for Audio FiltersAll Examples for Video FiltersAll Examples for Audio/Video SourcesAll Examples for Media FiltersIntroduce Usage of FFplayMore NotesGLTransition Filterfromffmpegimportavfilters,input,vfilters,vtoolsfromffmpeg.transitionsimportGLTransition,GLTransitionAllfromtestsimportdata# OpenGL Transition"""Combine two videos with transition effects."""foreinGLTransitionAll:vtools.concat_2_videos_with_gltransition(data.TEST_OUTPUTS_DIR/(e+".mp4"),data.SHORT0,data.SHORT1,offset=1,duration=2,source=eval("transitions."+e))"""Combine multiple videos with transition effects."""in0=input(data.SHORT0).videoin1=input(data.SHORT1).videoin2=input(data.SHORT2).videoin0_split=in0.split()in0_0,in0_1=in0_split[0],in0_split[1]in0_0=in0_0.trim(start=0,end=3)in0_1=in0_1.trim(start=3,end=4).setpts()in1_split=in1.split()in1_0,in1_1=in1_split[0],in1_split[1]in1_0=in1_0.trim(start=0,end=3)in1_1=in1_1.trim(start=3,end=4).setpts()in2_split=in2.split()in2_0,in2_1=in2_split[0],in2_split[1]in2_0=in2_0.trim(start=0,end=3)in2_1=in2_1.trim(start=3,end=4).setpts()gl0_1=vfilters.gltransition(in0_1,in1_0,source=GLTransition.Angular)gl1_2=vfilters.gltransition(in1_1,in2_0,source=GLTransition.ButterflyWaveScrawler)# transition_=avfilters.concat(in0_0,gl0_1,gl1_2,in2_1).output(data.TEST_OUTPUTS_DIR/"3_transition.mp4",vcodec="libx264",v_profile="baseline",preset="slow",movflags="faststart",pixel_format="yuv420p",).run()# transition + image watermarkv_input=avfilters.concat(in0_0,gl0_1,gl1_2,in2_1)i_input=input(data.I1).scale(w=100,h=100)v_input.overlay(i_input,x=30,y=30).output(data.TEST_OUTPUTS_DIR/"3_transition_image.mp4",vcodec="libx264",v_profile="baseline",preset="slow",movflags="faststart",pixel_format="yuv420p",).run()# transition + image watermark + text watermarkv_input=avfilters.concat(in0_0,gl0_1,gl1_2,in2_1).\drawtext(text="Watermark",x=150,y=150,fontsize=36,fontfile=data.FONT1)i_input=input(data.I1).scale(w=100,h=100)v_input.overlay(i_input,x=30,y=30).output(data.TEST_OUTPUTS_DIR/"3_transition_image_text.mp4",vcodec="libx264",v_profile="baseline",preset="slow",movflags="faststart",pixel_format="yuv420p",).run()# transition + image watermark + text watermark + musicv_input=avfilters.concat(in0_0,gl0_1,gl1_2,in2_1).\drawtext(text="Watermark",x=150,y=150,fontsize=36,fontfile=data.FONT1)i_input=input(data.I1).scale(w=100,h=100)a_input=input(data.A1).audiov_input.overlay(i_input,x=30,y=30).output(a_input,data.TEST_OUTPUTS_DIR/"3_transition_image_text_music.mp4",acodec="copy",vcodec="libx264",v_profile="baseline",shortest=True,preset="slow",movflags="faststart",pixel_format="yuv420p",).run()Video SourcesPlay by FFplayfromffmpegimportrun_ffplay_=run_ffplay("allrgb",f="lavfi")_=run_ffplay("allyuv",f="lavfi")_=run_ffplay("color=c=red@0.2:s=1600x900:r=10",f="lavfi")_=run_ffplay("haldclutsrc",f="lavfi")_=run_ffplay("pal75bars",f="lavfi")_=run_ffplay("allyuv",f="lavfi")_=run_ffplay("allyuv",f="lavfi")_=run_ffplay("rgbtestsrc=size=900x600:rate=60",f="lavfi")_=run_ffplay("smptebars=size=900x600:rate=60",f="lavfi")_=run_ffplay("smptehdbars=size=900x600:rate=60",f="lavfi")_=run_ffplay("testsrc=size=900x600:rate=60",f="lavfi")_=run_ffplay("testsrc2=s=900x600:rate=60",f="lavfi")_=run_ffplay("yuvtestsrc=s=900x600:rate=60",f="lavfi")Preview by FFmpegfromffmpegimportinput_source_=input_source("testsrc",size="900x600",rate=60).output(preview=True).run_async()_=input_source("testsrc2",size="900x600",rate=60).output(preview=True).run_async()Save Video from video sourcesfromffmpegimportinput_source_=input_source("testsrc",size="900x600",rate=60,duration=30).output("source_testsrc.mp4").run()More ExamplesGet Stream InfofromffmpegimportFFprobemeta=FFprobe("path/to/file")# all streamprint(meta.metadata)# video streamprint(meta.video)print(meta.video_duration)print(meta.video_scale)# audio streamprint(meta.audio)print(meta.audio_duration)Play a Videofromffmpegimportffplay_videofromtestsimportdataffplay_video(data.V1,vf='transpose=1')ffplay_video(data.V1,vf='hflip')ffplay_video(data.V1,af='atempo=2')ffplay_video(data.V1,vf='setpts=PTS/2')ffplay_video(data.V1,vf='transpose=1,setpts=PTS/2',af='atempo=2')Generate Thumbnail for Videofromffmpegimportvtoolsvtools.generate_video_thumbnail(src="src",dst="dst",start_position=3,width=400,height=-1)Convert Video to Numpy Arrayfromffmpegimportvtoolsvtools.convert_video_to_np_array(src="src")Read Single Video Frame as JPEGfromffmpegimportvtoolsvtools.read_frame_as_jpeg(src="src",frame=10)Convert Sound to Raw PCM Audiofromffmpegimportatoolsaudio='/path/to/audio.m4a'dst='/path/to/dst.pcm'atools.convert_audio_to_raw_pcm(src=audio,dst=None)atools.convert_audio_to_raw_pcm(src=audio,dst=dst)Assemble Video from Sequence of Framesfromffmpegimportvtools# on Linuxvtools.assemble_video_from_images('/path/to/jpegs/*.jpg',pattern_type='glob',frame_rate=25)# on Windowsvtools.assemble_video_from_images('/path/to/jpegs/%02d.jpg',pattern_type=None,frame_rate=25)https://stackoverflow.com/questions/31201164/ffmpeg-error-pattern-type-glob-was-selected-but-globbing-is-not-support-ed-byWith additional filtering:importffmpegffmpeg.input('/path/to/jpegs/*.jpg',pattern_type='glob',framerate=25).\filter('deflicker',mode='pm',size=10).\filter('scale',size='hd1080',force_original_aspect_ratio='increase').\output('movie.mp4',crf=20,preset='slower',movflags='faststart',pix_fmt='yuv420p').\view(save_path='filter_graph').run()Audio/Video Pipelineimportffmpegfromffmpegimportavfiltersin1=ffmpeg.input("input.mp4")in2=ffmpeg.input("input.mp4")v1=in1.video.hflip()a1=in2.audiov2=in2.video.reverse().hue(s=0)a2=in2.audio.areverse().aphaser()joined=avfilters.concat(v1,a1,v2,a2,v=1,a=1).Nodev3=joined[0]a3=joined[1].volume(0.8)v3.output(a3,'v1_v2_pipeline.mp4').run()Mono to Stereo with Offsets and Videoimportffmpegfromffmpegimportafiltersfromtestsimportdatainput_video=ffmpeg.input(data.V1)audio_left=ffmpeg.input(data.A1).atrim(start=15).asetpts("PTS-STARTPTS")audio_right=ffmpeg.input(data.A1).atrim(start=10).asetpts("PTS-STARTPTS")afilters.join(audio_left,audio_right,inputs=2,channel_layout="stereo").\output(input_video.video,"stereo_video.mp4",shortest=None,vcodec="copy").run()Process FramesDecode input video with ffmpegProcess each video frame with pythonEncode output video with ffmpegimportsubprocessimportnumpyasnpfromffmpegimportconstants,FFprobe,input,settingsfromtestsimportdatasettings.CUDA_ENABLE=Falsedefffmpeg_input_process(src):returninput(src).output(constants.PIPE,format="rawvideo",pixel_format="rgb24").run_async(pipe_stdout=True)defffmpeg_output_process(dst,width,height):returninput(constants.PIPE,format="rawvideo",pixel_format="rgb24",width=width,height=height).output(dst,pixel_format="yuv420p").\run_async(pipe_stdin=True)defread_frame_from_stdout(process:subprocess.Popen,width,height):frame_size=width*height*3input_bytes=process.stdout.read(frame_size)ifnotinput_bytes:returnassertlen(input_bytes)==frame_sizereturnnp.frombuffer(input_bytes,np.uint8).reshape([height,width,3])defprocess_frame_simple(frame):# deep dreamreturnframe*0.3defwrite_frame_to_stdin(process:subprocess.Popen,frame):process.stdin.write(frame.astype(np.uint8).tobytes())defrun(src,dst,process_frame):width,height=FFprobe(src).video_scaleinput_process=ffmpeg_input_process(src)output_process=ffmpeg_output_process(dst,width,height)whileTrue:input_frame=read_frame_from_stdout(input_process,width,height)ifinput_frameisNone:breakwrite_frame_to_stdin(output_process,process_frame(input_frame))input_process.wait()output_process.stdin.close()output_process.wait()if__name__=='__main__':run(data.SHORT0,data.TEST_OUTPUTS_DIR/"process_frame.mp4",process_frame_simple)FaceTime Webcam Inputimportffmpegdeffacetime():ffmpeg.input("FaceTime",format="avfoundation",pixel_format="uyvy422",framerate=30).\output("facetime.mp4",pixel_format="yuv420p",frame_size=100).run()Stream from a Local Video to HTTP Serverfromffmpegimportinputinput("video.mp4").output("http://127.0.0.1:8080",codec="copy",# use same codecs of the original videolisten=1,# enables HTTP serverf="flv").\with_global_args("-re").\run()# argument to act as a live streamTo receive the video you can use ffplay in the terminal:ffplay-fflvhttp://localhost:8080Stream from RTSP Server to TCP Socketimportsocketfromffmpegimportinputserver=socket.socket()process=input('rtsp://%s:8554/default').\output('-',format='h264').\run_async(pipe_stdout=True)whileprocess.poll()isNone:packet=process.stdout.read(4096)try:server.send(packet)exceptsocket.error:process.stdout.close()process.wait()breakSpecial ThanksThe FFmpeg-Python Project