lipku / python_rtmpstream

python库,实现推送实时rtmp音视频流
MIT License
68 stars 20 forks source link

视频推流后画面延迟问题 #15

Open star336 opened 3 months ago

star336 commented 3 months ago

画面效果来看 ,播放倍速不是1,像是只有0.6,0.7的样子 image 这是推流调试的提示参数,有数据延迟,但是没明白,需要从哪里调整? 视频是MP4 1080p,h264的编码,音频没有播放出来,我把声音代码注释了 image image image 希望有空帮忙解答下 感谢

lipku commented 3 months ago

不要把声音代码注释了,两者有个同步等待

star336 commented 2 months ago

确实是关闭声音导致的 开启声音同步就好了 。

另外一个问题 想请教下 目前获取音频列子有从本地声卡和还有从本地文件中获取,方便写一个从rtsp中获取音频吗,从rtsp中获取视频帧列子,示例已经实现了。尝试自己从rtsp中获取,方法是使用ffmpeg,提取音频,按照示例的大小来获取,但是一会就回报错,提示队列等待时前后差异太大 强制丢包。这个有什么解决办法吗?给些提示 或者方便写个示例 非常感谢

star336 commented 2 months ago

image import numpy as np import cv2 import time import subprocess from queue import Queue from threading import Thread

import pyaudio from rtmp_streaming import StreamerConfig, Streamer

def _read_frame_from_ffmpeg(queue, chunk_size): audio_file_path = "path_to_your_audio_file.mp3" # 替换为您的音频文件路径 command = [ 'ffmpeg', '-i', audio_file_path, '-f', 's16le', '-acodec', 'pcm_s16le', '-ar', '16000', '-ac', '1', '-' ]

process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

while True:
    audio_data = process.stdout.read(chunk_size)
    if not audio_data:
        break
    frame = np.frombuffer(audio_data, dtype=np.int16).astype(np.float32) / 32767
    queue.put(frame)

def main(): cap = cv2.VideoCapture("rtsp://admin:123456@192.168.10.29/mpeg4") ret, frame = cap.read() print(frame.shape)

sc = StreamerConfig()
sc.source_width = frame.shape[1]
sc.source_height = frame.shape[0]
sc.stream_width = 1920
sc.stream_height = 1080
sc.stream_fps = 25
sc.stream_bitrate = 1000000
sc.stream_profile = 'main'
sc.audio_channel = 1
sc.sample_rate = 16000
sc.stream_server = 'rtmp://alilive7.zhendongsport.com/zhendong/456?auth_key=1713406856-0-0-44ce2548291511f4aeee419a1115dee3'

streamer = Streamer()
streamer.init(sc)
streamer.enable_av_debug_log()

fps = 25
sample_rate = 16000
chunk = sample_rate // fps
audio_queue = Queue()
process_read_frame = Thread(target=_read_frame_from_ffmpeg, args=(audio_queue, chunk))
process_read_frame.start()

prev = time.time()

show_cap = True

while True:
    ret, frame = cap.read()
    now = time.time()
    duration = now - prev
    streamer.stream_frame(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
    while not audio_queue.empty():
        audio_frame = audio_queue.get()
        streamer.stream_frame_audio(audio_frame)
    prev = now
    if show_cap:
        cv2.imshow('frame', frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

cap.release()
if show_cap:
    cv2.destroyAllWindows()

if name == "main": main() 这里是代码

star336 commented 2 months ago

@lipku

lipku commented 2 months ago

请参考一下其他几个例子吧,分别给了读文件和实时视频的例子。