import cv2
import time
import numpy as np
import av
import av.datasets
import librosa
from fractions import Fraction
# 创建一个 FLV 容器
container = av.open('rtmp://test-push.xxxxx.com/livetest/video1', mode='w', format='flv')
# container = av.open('video1.flv', mode='w')
# 添加视频流
w = 256
h = 256
stream = container.add_stream('h264', rate=25, gop_size=1) # 使用 H264 编码器,fps
stream.width = w # 设置视频宽度
stream.height = h # 设置视频高度
stream.pix_fmt = 'yuv420p' # 设置像素格式
stream.gop_size = 1
# 添加音频流
AUDIO_SAMPLE_RATE = 24000
audio_stream = container.add_stream("aac", rate=AUDIO_SAMPLE_RATE) # 使用 AAC 编码器
audio_stream.layout = 'mono' # 设置音频格式
audio_stream.channels = 1 # 设置音频通道
speech_array, sample = librosa.load('input.wav', sr=24000) # 获取PCM
speech_array = (speech_array*32767).astype(np.int16) # 转为整型
mod = len(speech_array) % 24000
if mod > 0:
cat_array = np.zeros(24000-mod, dtype=np.int16)
speech_array = np.concatenate((speech_array, cat_array), axis=0)
print('speech_array', speech_array, len(speech_array))
audio_format="s16" #pyav的s16 就是 s16le
#准备图像数据
im = cv2.imread('53aa2b30a940.png')
im = cv2.resize(im, (w,h))
print(im.shape)
# 创建视频帧
for i in range(len(speech_array)//AUDIO_SAMPLE_RATE):
img_frame = av.VideoFrame.from_ndarray(im, format='bgr24')
for f in range(25):
img_frame.time_base = Fraction(1, 25000)
img_frame.pts = (i*25 + f)*1000
for packet in stream.encode(img_frame):
container.mux(packet)
audio_frame = av.AudioFrame(audio_format, layout='mono', samples=AUDIO_SAMPLE_RATE)
audio_frame.rate = AUDIO_SAMPLE_RATE
audio_bytes = speech_array[i*AUDIO_SAMPLE_RATE:(i+1)*AUDIO_SAMPLE_RATE] #b"\x00\x00" * frame_size
audio_frame.planes[0].update(audio_bytes)
audio_frame.time_base = Fraction(1, AUDIO_SAMPLE_RATE)
audio_frame.pts = i * AUDIO_SAMPLE_RATE
for packet in audio_stream.encode(audio_frame):
container.mux(packet)
time.sleep(1)
print(f'index={i}')
# 关闭容器
container.close()
python 使用 PyAV 进行 rtmp 直播推流
发布时间 2023-10-08 17:24:42作者: gaobowen