av
Windows : pip install av
Linux : sudo pip3 install av
av 調用ffmpeg 的sdk來執行的, 可以作更精細的動作. 只可惜的是, 並不支援硬体編碼. 而且官方也說了, 硬体編碼不在此專案的計畫當中, 看來只能死心了.
存成圖片
底下代碼, 可以把影片裏的frame一幅一幅的存成 jpg圖片檔
ffmpeg指令 : ffmpeg -i ../snake.mkv -r 1 img-%5d.jpg
-r 1 : 每秒取一張. 數字可以自已變更
#!/usr/bin/python3 import av container = av.open("../snake.mkv") stream = container.streams.video[0] stream.codec_context.skip_frame = 'NONKEY' for frame in container.decode(stream): frame.to_image().save('f-%04d.jpg' % frame.pts)
轉換格式
import av import av.datasets input_ = av.open(path_to_video) output = av.open('remuxed.mkv', 'w') in_stream = input_.streams.video[0] out_stream = output.add_stream(template=in_stream) for packet in input_.demux(in_stream): if packet.dts is None: continue packet.stream = out_stream output.mux(packet) output.close()
推播到rtmp
下面代碼, 可以自web cam取得影像, 解碼成 image後, 處理image, 然後再推播到rtmp. 只可惜 output_的編碼器若使用 h264_omx, 則整個會當掉. 此為PyAv的bug, 目前尚無解
所以只能用軟体編碼 “h264”, fps 只剩下 5fps. 所以目前放棄使用 PyAv
#!/usr/bin/python3 import av import cv2 from datetime import datetime input_ = av.open("/dev/video0") in_stream=input_.streams.video[0] in_stream.options={"input_format":"mjpeg", "video_size":"1920x1080"} #in_stream.width=1920 #in_stream.height=1080 output_=av.open('rtmp://mahaljsp.asuscomm.com/live/car',mode='w', format='flv') output_stream = output_.add_stream(codec_name="h264",rate=24) output_stream.options = {"b":"4000k", "vcodec":"libx264", "video_size":"1920x1080"} t1=datetime.now() t2=t1 index=0 for frame in input_.decode(in_stream): for packet in output_stream.encode(frame): output_.mux(packet) t2=datetime.now() if (t2-t1).seconds>0: print(index) index=0 t1=t2 else: index+=1 cv2.waitKey(5) output_.close()
轉換成image再推播
此方式因要處理圖片, 所以要先 sudo pip3 install Pillow ttf-wqy-zenhei
#!/usr/bin/python3 import av import time import cv2 from PIL import ImageDraw from PIL import ImageFont from datetime import datetime infile = av.open("/dev/video0") instream=infile.streams.video[0] instream.options={"input_format":"mjpeg", "video_size":"1920x1080"} outfile=av.open('rtmp://mahaljsp.asuscomm.com/live/car',mode='w', format='flv') outstream = outfile.add_stream(codec_name="h264",rate=24) outstream.options = {"b":"4000k", "vcodec":"h264_omx", "video_size":"1920x1080", "threads":"16"} t1=round(time.time() * 1000) t2=t1 index=0 for packet in infile.demux(): frame=packet.decode()[0] img = frame.to_image() datetime_dt = datetime.today() # 獲得當地時間 datetime_str = datetime_dt.strftime("%Y/%m/%d %H:%M:%S") # 格式化日期 draw = ImageDraw.Draw(img) draw.text((10,30), datetime_str, font=ImageFont.truetype("/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc",36), fill=(0, 255, 255, 255)) #底下這最編碼, 在樹莓派若採軟体編碼, 非常的慢, 頂多 2fps而以 out_packet = outstream.encode(av.VideoFrame.from_image(img)) outfile.mux(out_packet) t2=round(time.time() * 1000) if (t2-t1)>=1000: print(index) index=0 t1=round(time.time() * 1000) else: index+=1
Windows 版
#!/usr/bin/python3 import av import time import cv2 from PIL import ImageDraw from PIL import ImageFont from datetime import datetime #infile = av.open("/dev/video0") infile = av.open("c922 Pro Stream Webcam", mode='r', format='vfwcap') instream=infile.streams.video[0] instream.options={"input_format":"mjpeg", "video_size":"1920x1080"} outfile=av.open('rtmp://mahaljsp.asuscomm.com/live/car',mode='w', format='flv') outstream = outfile.add_stream(codec_name="h264_nvenc",rate=24) outstream.options = {"b":"4000k", "video_size":"1920x1080", "threads":"16"} t1=round(time.time() * 1000) t2=t1 index=0 for packet in infile.demux(): frame=packet.decode()[0] img = frame.to_image() datetime_dt = datetime.today() # 獲得當地時間 datetime_str = datetime_dt.strftime("%Y/%m/%d %H:%M:%S") # 格式化日期 draw = ImageDraw.Draw(img) #draw.text((10,30), datetime_str, font=ImageFont.truetype("/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc",36), fill=(0, 255, 255, 255)) draw.text((10, 30), datetime_str, font=ImageFont.truetype("arial.ttf", 36),fill=(0, 255, 255, 255)) #底下這最編碼, 在樹莓派若採軟体編碼, 非常的慢, 頂多 2fps而以 out_packet = outstream.encode(av.VideoFrame.from_image(img)) outfile.mux(out_packet) t2=round(time.time() * 1000) if (t2-t1)>=1000: print(index) index=0 t1=round(time.time() * 1000) else: index+=1
ffmpy3
Windows : pip install ffmpy3
Linux : sudo pip3 install ffmpy3
ffmpy3好像是去執行ffmpeg這支程式的, 還不確定, 測試中
ffmpy3是在Python裏調用ffmpeg這支程式, 進行音視訊的操作, 記得將 ffmpeg這支程式放在專案裏
blog.csdn.net/qq_40962368/article/details/91355429