You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

运行Reddit视频合并脚本时FFmpeg仅输出版本信息,如何修复?

问题修复方案

核心问题分析

  1. Reddit视频URL获取错误:直接使用submission.url得到的是视频网页链接,并非实际视频文件地址,导致下载的是网页而非视频,文件自然损坏。
  2. 视频下载不完整:requests.get直接写入大文件易因网络问题中断,引发文件损坏。
  3. FFmpeg命令无效:冗余参数-strict experimental在新版FFmpeg中已无需使用,且未对文件名添加引号,若文件名含空格会导致命令解析失败,仅输出版本信息。
  4. 资源未正确释放与临时文件未清理:临时视频文件未被删除,且cv2.VideoCapture占用文件可能导致后续操作异常。

修复步骤与代码修改

1. 正确获取Reddit视频源地址

替换视频URL提取逻辑,从submission.media['reddit_video']中获取实际视频文件的fallback_url:

video_urls = []
for submission in submissions:
    if submission.media and 'reddit_video' in submission.media:
        video_url = submission.media['reddit_video']['fallback_url']
        video_urls.append(video_url)

2. 分块下载视频避免损坏

修改download_video函数,分块写入文件提升稳定性:

def download_video(url, filename):
    with requests.get(url, stream=True) as response:
        response.raise_for_status()
        with open(filename, 'wb') as f:
            for chunk in response.iter_content(chunk_size=8192):
                f.write(chunk)

3. 修正FFmpeg命令

移除冗余参数,对文件名添加引号处理空格问题:

ffmpeg_cmd = f'ffmpeg -i "{output_filename}" -i "combined_audio.mp3" -c:v copy -c:a aac -map 0:v:0 -map 1:a:0 "final_output.mp4"'
os.system(ffmpeg_cmd)

4. 完整清理临时文件

在函数末尾添加临时视频文件的删除逻辑,确保资源释放后再删除:

# 清理所有临时文件
for i in range(len(video_urls)):
    temp_file = f'temp_video_{i}.mp4'
    if os.path.exists(temp_file):
        os.remove(temp_file)
if os.path.exists("combined_audio.mp3"):
    os.remove("combined_audio.mp3")

完整修复后的代码

import praw
import requests
import cv2
import os
from pydub import AudioSegment

def download_video(url, filename):
    # 分块下载视频,避免文件损坏
    with requests.get(url, stream=True) as response:
        response.raise_for_status()
        with open(filename, 'wb') as f:
            for chunk in response.iter_content(chunk_size=8192):
                f.write(chunk)

def combine_videos(video_urls, output_filename):
    video_clips = []
    audio_clips = []
    for i, url in enumerate(video_urls):
        temp_filename = f'temp_video_{i}.mp4'
        download_video(url, temp_filename)
        # 读取视频与音频
        video_clip = cv2.VideoCapture(temp_filename)
        audio_clip = AudioSegment.from_file(temp_filename, format="mp4")
        video_clips.append(video_clip)
        audio_clips.append(audio_clip)
    
    if not video_clips:
        print("No video clips to combine.")
        return

    # 获取视频基础参数
    frame_width = int(video_clips[0].get(cv2.CAP_PROP_FRAME_WIDTH))
    frame_height = int(video_clips[0].get(cv2.CAP_PROP_FRAME_HEIGHT))
    fps = video_clips[0].get(cv2.CAP_PROP_FPS)
    # 使用更兼容的编码格式
    fourcc = cv2.VideoWriter_fourcc(*'avc1')
    output_clip = cv2.VideoWriter(output_filename, fourcc, fps, (frame_width, frame_height))

    # 写入视频帧
    for video_clip in video_clips:
        video_clip.set(cv2.CAP_PROP_POS_FRAMES, 0)  # 重置视频读取指针
        while True:
            ret, frame = video_clip.read()
            if not ret:
                break
            output_clip.write(frame)
    
    # 释放视频资源
    for video_clip in video_clips:
        video_clip.release()
    output_clip.release()

    # 合并音频
    combined_audio = sum(audio_clips)
    combined_audio.export("combined_audio.mp3", format="mp3")

    # 修正后的FFmpeg合并命令
    ffmpeg_cmd = f'ffmpeg -i "{output_filename}" -i "combined_audio.mp3" -c:v copy -c:a aac -map 0:v:0 -map 1:a:0 "final_output.mp4"'
    os.system(ffmpeg_cmd)

    # 清理所有临时文件
    for i in range(len(video_urls)):
        temp_file = f'temp_video_{i}.mp4'
        if os.path.exists(temp_file):
            os.remove(temp_file)
    if os.path.exists("combined_audio.mp3"):
        os.remove("combined_audio.mp3")

def main():
    reddit = praw.Reddit(
        client_id='XXX',
        client_secret='XXX',
        user_agent='Reddit Video Downloader'
    )
    
    subreddit_name = input("Enter the name of the subreddit: ")
    limit = int(input("Enter the number of videos to download: "))
    
    subreddit = reddit.subreddit(subreddit_name)
    submissions = subreddit.hot(limit=limit)
    
    # 正确提取Reddit视频源地址
    video_urls = []
    for submission in submissions:
        if submission.media and 'reddit_video' in submission.media:
            video_url = submission.media['reddit_video']['fallback_url']
            video_urls.append(video_url)
    
    if video_urls:
        output_filename = input("Enter the output filename (e.g., output.mp4): ")
        combine_videos(video_urls, output_filename)
        print("Videos combined successfully!")
    else:
        print("No Reddit videos found in the subreddit.")

if __name__ == "__main__":
    main()

内容的提问来源于stack exchange,提问作者Oreo F

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 08:54:58