python - 在不下载视频的情况下提取 youtube 视频的特定帧

标签 python opencv ffmpeg video-capture youtube-dl

我需要提取在线视频的特定帧来处理算法,但我不想下载整个视频,因为那样会非常低效。

首先,我尝试使用 YouTube 视频。我可以这样使用 youtube-dl 下载整个视频:

ydl_opts = {'outtmpl': r'OUTPUT_DIRECTORY_HERE',}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
    ydl.download([url])

然后我可以捕捉单独的帧。

我需要避免下载整个视频。经过一些研究,我发现 ffmpeg 可以帮助我做到这一点。我发现无法只下载帧,所以如果这不可能,第二种选择是我可以下载视频的特定部分。 Linux 中的一个这样的例子是 here但我找不到任何适用于 python 的解决方案。

什么是只下载帧或部分视频(在 python 中)而不下载整个内容的好方法?

最佳答案

只是为了补充当前的答案,使用多处理可以进一步提高性能。例如,如果您想将视频分割成帧并在 num_cpu 个进程中独立处理它们:

import os
from functools import partial
from multiprocessing.pool import Pool

import cv2
import youtube_dl

def process_video_parallel(url, skip_frames, process_number):
    cap = cv2.VideoCapture(url)
    num_processes = os.cpu_count()
    frames_per_process = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) // num_processes
    cap.set(cv2.CAP_PROP_POS_FRAMES, frames_per_process * process_number)
    x = 0
    count = 0
    while x < 10 and count < frames_per_process:
        ret, frame = cap.read()
        if not ret:
            break
        filename =r"PATH\shot"+str(x)+".png"
        x += 1
        cv2.imwrite(filename.format(count), frame)
        count += skip_frames  # Skip 300 frames i.e. 10 seconds for 30 fps
        cap.set(1, count)
    cap.release()



video_url = "..."  # The Youtube URL
ydl_opts = {}
ydl = youtube_dl.YoutubeDL(ydl_opts)
info_dict = ydl.extract_info(video_url, download=False)

formats = info_dict.get('formats', None)

print("Obtaining frames")
for f in formats:
    if f.get('format_note', None) == '144p':
        url = f.get('url', None)
        cpu_count = os.cpu_count()
        with Pool(cpu_count) as pool:
            pool.map(partial(process_video_parallel, url, 300), range(cpu_count))

出于此应用程序的目的,由于只是从视频中保存图像,因此这可能不会带来巨大的改进(可能几秒钟),但如果需要在帧上应用其他算法,则可能是有益。

关于python - 在不下载视频的情况下提取 youtube 视频的特定帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66272740/

相关文章:

ffmpeg - 色度键我的过滤白色背景命令有效,但过滤白色和黑色?

ubuntu - ubuntu 中的 ffmpeg 问题(libavcodec.so)

python - 调用 PyEval_CallObject 时程序关闭

python - pip: sys.stderr.write(f"ERROR: {exc}") 使用 Python 3.5

c++ - 在 opencv 中手动构造一个 vector <Dmatch>

opencv - 在png文件中找到汇编代码是否正常?

c++ - 写入和读取opencv3.0 ml文件(随机森林)

ffmpeg - 如何使用 ffmpeg 添加专辑封面?

python - 在 python 中转换列表以自定义字典

Python 断言等于生成器