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

Android中pytube+chaquopy流式加载视频耗时过长的优化咨询

Android下Chaquopy+Pytube实现YouTube流式播放的加载优化问题

我在Android平台借助Chaquopy工具,使用Pytube实现YouTube视频流式播放功能,相关代码如下:

videofile.py

from pytube import YouTube
def video(link):
    yt = YouTube(f'https://www.youtube.com/watch?v=' + link)
    stream_url = yt.streams.get_highest_resolution().url
    return stream_url

VideoActivityPy.java

progressBar = findViewById(R.id.pro);
videoView = findViewById(R.id.videoview);
new Thread(() -> {
    try {
        if (!Python.isStarted()) {
            Python.start(new AndroidPlatform(VideoActivityPy.this));
        }
        python = Python.getInstance();
        pyScript = python.getModule("videofile");
        videoUri = pyScript.callAttr("video", MyData.videoLink);
        runOnUiThread(() -> {
            videoView.setSystemUiVisibility(
                                  View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                                | View.SYSTEM_UI_FLAG_FULLSCREEN
                                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
            Uri uri = Uri.parse(videoUri.toString());
            videoView.setVideoURI(uri);
            MediaController mediaController = new MediaController(VideoActivityPy.this);
            mediaController.setAnchorView(videoView);
            mediaController.setMediaPlayer(videoView);
            videoView.setMediaController(mediaController);
            videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mediaPlayer) {
                    progressBar.setVisibility(View.INVISIBLE);
                    videoView.start();
                }
            });
       });
    }
    catch (com.chaquo.python.PyException pyException) {
        progressBar.setVisibility(View.INVISIBLE);
        Toast.makeText(VideoActivityPy.this, "Check your internet connection", Toast.LENGTH_LONG).show();
    } 
    catch (Exception e) {
        progressBar.setVisibility(View.INVISIBLE);
        Toast.makeText(VideoActivityPy.this, e.toString(), Toast.LENGTH_LONG).show();
    }
}).start();

最初未使用线程时应用出现ANR问题,添加线程后功能正常,但视频启动加载耗时约40-50秒(视频时长1.5小时)。我已从PyPI下载pytube-15.0.0.tar.gz并修改了其中cipher.py文件的var_regex配置,gradle配置如下:

python {
    buildPython "C:/Python38/python.exe"
    pip {
        install "pytube-15.0.0.tar.gz"
    }
}

请问有什么方法可以缩短视频加载时间?


解决方案
  • 提前初始化Python环境:当前代码在每次请求视频时才检查并启动Python,这部分初始化会占用不少时间。建议在自定义Application的onCreate方法中提前启动Python,而非在播放线程中处理:

    // 在自定义Application类中
    @Override
    public void onCreate() {
        super.onCreate();
        if (!Python.isStarted()) {
            Python.start(new AndroidPlatform(this));
        }
    }
    

    这样进入播放页面时Python已经就绪,省去初始化耗时。

  • 优化Pytube的调用逻辑:

    • 创建YouTube对象时,禁用不必要的功能减少元数据拉取:
      yt = YouTube(f'https://www.youtube.com/watch?v=' + link, use_oauth=False, allow_oauth_cache=False)
      
      避免Pytube处理OAuth相关的额外逻辑,减少网络请求次数。
    • 精准过滤流类型,避免拉取所有流信息:如果只需要包含音视频的渐进式流,直接过滤后获取最高分辨率,减少数据解析量:
      stream_url = yt.streams.filter(progressive=True).get_highest_resolution().url
      
    • 缓存已解析的流URL:对同一视频链接,解析一次后将URL缓存到本地(如SharedPreferences),后续播放直接使用缓存值,无需重复解析。
  • 替换为更轻量的视频解析方案:Pytube 15.0.0版本较旧,且包含较多非必要功能。可以考虑直接在Java层发起网络请求获取YouTube页面HTML,手动解析签名和流URL,避免Python层的性能开销;或者尝试整合yt-dlp的核心解析逻辑(需注意Chaquopy的兼容性)。

  • 优化网络请求性能:

    • 替换Pytube默认的网络请求库:Pytube使用urllib,在Android上性能不如原生OkHttp。可以在Java层用OkHttp获取YouTube页面的HTML,再传递给Python层解析签名和流URL,减少网络请求耗时。
    • 启用网络缓存:给网络请求添加缓存策略,避免重复拉取相同的页面资源,比如通过OkHttp配置缓存,或在Python层给urllib添加缓存处理。
  • 预加载流信息:在用户进入播放页面之前(比如列表页面点击视频时),提前在后台线程中解析视频的流URL,存储到全局变量或本地缓存中。用户进入播放页面时直接使用已准备好的URL,跳过解析等待时间。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 22:34:55