写入使用导入流链接模块或运行子进程或操作系统.系统命令吗?



我看到一些可用的流链接api,但几乎没有看到任何信息,如如何使用它的例子。

我实际上要做的是从一个特定的youtube频道捕获一个实时视频。

我只关心音频,而不是视频。因此,脚本的一部分将是在我使用streamlink捕获.ts视频文件之后,使用ffmpeg将其转换为。mp3。因为我不认为streamlink可以捕获实况流作为mp3?把文件转换成mp3最好的方法是什么?是否要在视频被捕获后运行ffmpeg命令,以便脚本将等待进一步运行,直到转换完成?

我认为可能更好的是将ffmpeg命令作为单独的线程或与streamlink分开的线程运行。这样,streamlink可以继续捕获/下载,而ffmpeg可以并行运行,同时将过去的。ts文件转换为mp3。

在os中运行streamlink似乎容易得多。系统或子进程,只需将streamlink作为传递所需参数的命令运行。

使用streamlink模块运行是否有任何优势?

我发现这个代码示例在这里:处理流作为单独的帧使用streamlink,但我有问题,我可以省略哪些部分是与视频相关的(因为我不关心流的视频部分)?

import numpy as np
import subprocess as sp
import threading
import cv2
import ffmpeg
#stream_url = 'https://www.nimo.tv/v/v-1712291636586087045'
stream_url = 'https://www.twitch.tv/esl_csgo'
# Assume video resolution is known.
width, height = 1920, 1080

# Writer thread (read from streamlink and write to FFmpeg in chunks of 1024 bytes).
def writer(streamlink_proc, ffmpeg_proc):
while (not streamlink_proc.poll()) and (not ffmpeg_proc.poll()):
try:
chunk = streamlink_proc.stdout.read(1024)
ffmpeg_proc.stdin.write(chunk)
except (BrokenPipeError, OSError) as e:
pass

streamlink_args = [r'c:Program Files (x86)Streamlinkbinstreamlink.exe', stream_url, "best", "-O"]  # Windows executable downloaded from: https://github.com/streamlink/streamlink/releases/tag/2.4.0
streamlink_process = sp.Popen(streamlink_args, stdout=sp.PIPE)  # Execute streamlink as sub-process

# Execute FFmpeg sub-process with URL as input and raw (BGR) output format.
ffmpeg_process = (
ffmpeg
.input('pipe:')
.video
.output('pipe:', format='rawvideo', pix_fmt='bgr24')
.run_async(pipe_stdin=True, pipe_stdout=True) # In case ffmpeg in not in executable path, add cmd=fullpath like: .run_async(pipe_stdout=True, cmd=r'c:FFmpegbinffmpeg.exe')
)

thread = threading.Thread(target=writer, args=(streamlink_process, ffmpeg_process))
thread.start()

# Read decoded video (frame by frame), and display each frame (using cv2.imshow)
while True:
# Read raw video frame from stdout as bytes array.
in_bytes = ffmpeg_process.stdout.read(width * height * 3)
if not in_bytes:
break
# Transform the byte read into a NumPy array
frame = np.frombuffer(in_bytes, np.uint8).reshape([height, width, 3])
# Display the frame
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
ffmpeg_process.stdout.close()
ffmpeg_process.wait()
#streamlink_process.stdin.close()
streamlink_process.kill()
cv2.destroyAllWindows()

我不确定是否cv2, numpy或"视频块";是否需要或有帮助,因为我对视频质量不感兴趣?

使用视频块下载的目的是什么?它对流下载的可靠性有帮助吗?

我需要帮助了解如何把我的脚本放在一起,哪些部分/模块会有帮助?

如果streamlink没有断开,您可以直接将该链接传递给FFmpeg。
建议的解决方案是在下载时录制音频。

  • 使用Streamlink模块从WEB地址获取直接视频流URL(如m3u8)
  • 将视频流URL传递给FFmpeg

决定何时以及如何终止记录可能有点棘手,因为我们希望优雅地关闭FFmpeg。
我使用输入来检查Esc键是否按下。

下面是完整的代码示例:

from streamlink import Streamlink
import ffmpeg
import signal
from pynput.keyboard import Key, Listener
from threading import Thread
import time
web_url = 'https://www.twitch.tv/esl_csgo'
esc_key_pressed = False  # Global variable.

def stream_to_url(url, quality='audio_only'):
# The "audio_only" quality may be invalid for some streams (check).
session = Streamlink()
streams = session.streams(url)
return streams[quality].to_url()

# Wait for Esc key to be pressed (and released).
def wait_for_esc_key():
global esc_key_pressed
# Collect events until released https://stackoverflow.com/questions/24072790/how-to-detect-key-presses
with Listener(on_press=None, on_release=lambda key: (False if key == Key.esc else True)) as listener:
listener.join()
esc_key_pressed = True    

# Get the stream URL from the WEB site URL:
stream_url = stream_to_url(web_url)
# Read the input stream from the link, and write the audio to audio.mp3 file.
ffmpeg_process = (
ffmpeg
.input(stream_url)
.audio
.output('audio.mp3')
.overwrite_output()
.run_async() # In case FFmpeg in not in executable path, add cmd=fullpath like: .run_async(cmd=r'c:FFmpegbinffmpeg.exe')
)

print('Press Esc to end recording')

# Wait for Esc key in a thread (non-blocking wait).
wait_for_esc_key_thread = Thread(target=wait_for_esc_key)
wait_for_esc_key_thread.start()

# Wait for Escape key pressed or FFmpeg finished.
while (not esc_key_pressed) and (not ffmpeg_process.poll()):
time.sleep(0.01)

if esc_key_pressed:
# Close FFmpeg gracefully
# https://stackoverflow.com/questions/67276793/output-always-corrupt-from-ffmpeg-using-selenium-python
ffmpeg_process.send_signal(signal.CTRL_C_EVENT)  # Is signal.CTRL_C_EVENT Windows only?

相关内容

  • 没有找到相关文章

最新更新