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对象时,禁用不必要的功能减少元数据拉取:
避免Pytube处理OAuth相关的额外逻辑,减少网络请求次数。yt = YouTube(f'https://www.youtube.com/watch?v=' + link, use_oauth=False, allow_oauth_cache=False) - 精准过滤流类型,避免拉取所有流信息:如果只需要包含音视频的渐进式流,直接过滤后获取最高分辨率,减少数据解析量:
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
相关产品推荐
相关产品推荐

