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

使用pytube下载YouTube视频后播放几秒停帧,音频正常

问题分析

合成后的视频播放几秒就停在静态画面但音频持续播放,核心原因包括:

  1. 音视频时长不匹配,视频播放完毕后画面静止但音频未结束
  2. 合成时未指定兼容的编码参数,导致播放器解析异常
  3. 直接覆盖原视频文件时,文件句柄未释放引发写入异常
修复方案

1. 优化流筛选逻辑

简化视频、音频流的筛选代码,避免无效遍历,确保获取正确的独立流:
修改module.py的video和audio函数:

import pytube
from moviepy.editor import *
import os.path

def video(link):
    yt = pytube.YouTube(link)
    # 精准筛选仅视频、1080p、MP4格式的流
    stream = yt.streams.filter(only_video=True, resolution="1080p", mime_type="video/mp4").first()
    if not stream:
        raise ValueError("未找到1080p的MP4视频流")
    stream.download(r"C:\Users\pc\PycharmProjects\youtube")
    return [stream.title, yt.length]

def audio(link):
    yt = pytube.YouTube(link)
    # 精准筛选仅音频、MP4格式的流
    stream = yt.streams.filter(only_audio=True, mime_type="audio/mp4").first()
    if not stream:
        raise ValueError("未找到MP4音频流")
    audio_path = os.path.join(r"C:\Users\pc\PycharmProjects\youtube", "Audio.mp4")
    stream.download(output_path=r"C:\Users\pc\PycharmProjects\youtube", filename="Audio.mp4")
    return [audio_path, yt.length]

2. 修复视频合成逻辑

对齐音视频时长,指定兼容编码,避免文件覆盖冲突:
修改module.py的mixer函数:

def mixer(video_path, audio_path, output_title):
    # 使用with语句自动释放文件句柄
    with VideoFileClip(video_path) as videoclip, AudioFileClip(audio_path) as audioclip:
        # 取音视频中较短的时长作为合成总时长,避免时长不匹配
        min_duration = min(videoclip.duration, audioclip.duration)
        videoclip_trimmed = videoclip.subclip(0, min_duration)
        audioclip_trimmed = audioclip.subclip(0, min_duration)
        
        # 替换音频并指定标准编码参数
        final_clip = videoclip_trimmed.set_audio(audioclip_trimmed)
        final_clip.write_videofile(
            output_title,
            codec="libx264",  # 通用视频编码
            audio_codec="aac", # 通用音频编码
            preset="medium"   # 平衡合成速度与质量
        )

3. 调整主程序避免文件覆盖

用临时文件合成后替换原视频,防止原文件被占用:
修改main.py:

from modules import *
import os
import time

link = "https://www.youtube.com/watch?v=CLk7A7HXhYQ"

vtitle = video(link)[0] + ".mp4"
atitle = audio(link)[0]
print("文件已下载")
time.sleep(1)
print("正在合成")

# 先合成到临时文件,避免覆盖原视频引发的冲突
temp_output = f"temp_{vtitle}"
mixer(vtitle, atitle, temp_output)

# 替换原视频文件
os.remove(vtitle)
os.rename(temp_output, vtitle)

print("合成完成")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 03:24:37