压缩视频上传至线上服务器后无法在Android VideoView播放求助
结合你提供的代码和Logcat日志,咱们来一步步定位这个视频播放失败的问题:
先抓日志里的关键线索
日志里明确出现了:
W/MediaPlayer: Couldn't open http://www.selfilife.com/App/media/priteshvishwakarma/post_video/VIDEO_20180522_122801.mp4: java.io.FileNotFoundException: No content provider: http://xxx.mp4
但你说视频确实存在、本地服务器能播、其他URL视频也正常,所以这个错误不是真的找不到文件,而是视频在网络传输/播放时的兼容性问题,下面是具体排查方向:
1. 检查线上服务器的Content-Type响应头
Android的MediaPlayer对视频文件的MIME类型要求很严格,线上服务器必须返回正确的video/mp4类型,而不是application/octet-stream或者其他错误类型。
- 你可以用浏览器开发者工具(Network面板)查看该视频URL的响应头,或者用命令行验证:
curl -I http://www.selfilife.com/App/media/priteshvishwakarma/post_video/VIDEO_20180522_122801.mp4 - 如果Content-Type不对,需要在服务器端配置:
- Apache可以修改
.htaccess文件,添加:AddType video/mp4 .mp4 - Nginx可以在对应的
location块里添加:types { video/mp4 mp4; }
- Apache可以修改
2. 检查压缩后视频的编码与封装格式
本地能播不代表网络能播,重点看两个核心点:
(1)编码标准
压缩后的视频必须使用Android MediaPlayer支持的标准编码:
- 视频编码:H.264(Baseline或Main Profile)
- 音频编码:AAC-LC
你可以用ffmpeg查看视频详细信息:
ffmpeg -i VIDEO_20180522_122801.mp4
如果编码不符合标准,需要调整压缩库的参数,或者用ffmpeg重新转码。
(2)MP4的moov原子位置
MP4文件里的moov原子(存储视频元数据)如果在文件尾部,MediaPlayer无法边下载边播放(网络播放需要先读取元数据),而本地播放是读取整个文件,所以不受影响。
- 用ffmpeg重新封装,把moov移到文件头部:
ffmpeg -i input.mp4 -movflags faststart output.mp4
然后把处理后的视频重新上传到服务器测试。
3. 检查服务器的跨域配置(如果APP和服务器域名不同)
如果你的APP和视频服务器不在同一个域名下,服务器需要配置CORS响应头,否则MediaPlayer可能无法正常加载资源:
- 服务器需要返回类似这样的响应头:
Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, POST, OPTIONS
4. 代码层面的优化建议
你的代码有两个小细节可以调整,避免潜在问题:
(1)把seekTo(1)移到onPrepared回调里
原代码里在设置URI后直接调用seekTo(1),此时视频还没准备好,可能导致异常。调整后:
vv.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { public void onPrepared(MediaPlayer mp) { mp.setLooping(true); vv.seekTo(1); // 移到这里,确保视频已准备好 vv.start(); } });
(2)添加错误监听,捕获更详细的错误信息
添加OnErrorListener可以帮你获取更具体的播放错误码,方便进一步排查:
vv.setOnErrorListener(new MediaPlayer.OnErrorListener() { @Override public boolean onError(MediaPlayer mp, int what, int extra) { Log.e("VideoPlayError", "Error Code: " + what + ", Extra: " + extra); return false; } });
总结
优先排查服务器的Content-Type设置和视频的moov原子位置,这两个是MP4网络播放失败最常见的原因——本地播放不受这些限制,所以会出现本地正常、线上异常的情况。
内容的提问来源于stack exchange,提问作者Pritesh Vishwakarma

