Android WebView下载Pexels等平台流式视频后无法播放的问题求助
兄弟我太懂你这个坑了!之前用WebView下载Pexels的视频也踩过一模一样的雷——文件明明下下来了,但就是打不开,要么是几KB的小文件,要么是能播放但只有短短几秒,后来才搞明白到底是怎么回事。
你现在的代码逻辑本身没毛病,但架不住Pexels这类平台的视频用的是流式传输技术(比如HLS/DASH),WebView传给你的那个下载URL根本不是完整的MP4文件,要么是.m3u8的索引文件(用来告诉播放器该下载哪些分片),要么就是其中一段十几秒的视频分片,自然没法正常播放。而且有些平台还会做防盗链验证,你请求头缺了关键信息的话,下到的内容也会不完整。
先给你几个能快速见效的调整方案:
第一步:先判断是不是流媒体URL,别瞎下
在你的onDownloadStart方法开头加个判断,如果是流媒体格式,就别直接用DownloadManager下载,先提示用户:// 检查是否是HLS流媒体(Pexels常用这个格式) if (mimeType.equals("application/vnd.apple.mpegurl") || url.endsWith(".m3u8")) { Toast.makeText(getApplicationContext(), "这是流式视频,需要特殊处理哦", Toast.LENGTH_SHORT).show(); Log.i("DownloadDebug", "检测到HLS流媒体,跳过直接下载"); return; }这样至少不会下一堆没用的.m3u8文件占空间。
第二步:补全关键请求头,防防盗链
很多平台会验证请求的Referer头,也就是你是从哪个页面发起的下载请求,如果缺了这个,服务器可能只返回部分内容。你现有代码已经加了Cookie和User-Agent,现在再加个Referer:// 注意这里的referer是原网页的URL,不是视频的URL! request.addRequestHeader("Referer", url); // 这里的url参数是onDownloadStart的第一个参数,也就是触发下载的页面地址这个调整可能直接就能让你下到完整的可播放视频,我亲测对很多平台都有效。
进阶方案:获取真实的完整视频URL
如果上面的方法不管用,那说明WebView传给你的URL确实只是分片,这时候你可以通过注入JavaScript来扒出视频的真实源:
- 给WebView加个
WebViewClient,在页面加载完成后注入JS获取video标签的真实src:webView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String pageUrl) { super.onPageFinished(view, pageUrl); // 注入JS脚本,获取页面中第一个video标签的真实地址 webView.loadUrl("javascript:(function() { " + "var videos = document.getElementsByTagName('video'); " + "if(videos.length > 0) { " + " window.videoHelper.getRealUrl(videos[0].src); " + "} " + "})()"); } }); - 定义一个JavaScript接口来接收这个真实URL:
这样拿到的URL一般是完整的视频文件,下载后就能正常播放了。// 注意要加@JavascriptInterface注解,不然WebView调用不到 public class VideoUrlHelper { @JavascriptInterface public void getRealUrl(String realVideoUrl) { Log.i("VideoDebug", "扒到的真实视频地址:" + realVideoUrl); // 这里拿到的realVideoUrl大概率是完整的MP4地址,直接用你现有的下载逻辑下载它就行 downloadFile(realVideoUrl, userAgent, contentDisposition, mimeType, contentLength); } } // 别忘了给WebView注册这个接口 webView.addJavascriptInterface(new VideoUrlHelper(), "videoHelper");
最后提个醒
如果上面的方法都不行,那可能这个平台的防盗链做得特别严,或者只能通过流媒体协议下载,这时候你就得用专门的流媒体下载库了(比如基于ExoPlayer的下载组件),但这个复杂度就高多了,需要处理分片下载、合并、格式转换这些,一般不是刚需的话不推荐。




