# FLV播放问题分析和解决方案 ## 问题描述 项目中播放FLV流 `https://devflytopull.codroner.com/live/flytodev-stream-7CTDL9K00A0121.flv` 时出现播放慢或无法播放的问题。 ## 问题分析 ### 1. FLV流本身正常 通过测试脚本验证,FLV流可以正常访问: - 响应时间:320ms - 平均速度:233KB/s - 内容类型:video/x-flv - FLV文件头正确 ### 2. Android项目中的问题 #### 2.1 播放器配置过于激进 **原问题**: - 缓冲区设置过小(256KB) - 探测大小过小(16字节) - 分析时间过短(50ms) - 超时时间过短(1秒) - 禁用了所有缓冲机制 **解决方案**: ```java // 使用更合理的缓冲设置 ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "max-buffer-size", "1024000"); // 1MB ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "probesize", "50000"); // 50KB ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzeduration", "100000"); // 100ms ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "timeout", "5000000"); // 5秒 ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "stimeout", "5000000"); // 5秒 // 启用缓冲机制 ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "packet-buffering", 1); ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "sync-av-start", 1); ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "infbuf", 1); ``` #### 2.2 Surface创建时机问题 **原问题**: - 在Surface创建前就调用了prepareAsync() - 可能导致播放器准备失败 **解决方案**: ```java // 在Surface创建后再开始准备 @Override public void surfaceCreated(@NonNull SurfaceHolder holder) { ijkPlayer.setDisplay(holder); if (!playerObj.isPlayerPlaying()) { ijkPlayer.prepareAsync(); } } ``` #### 2.3 缺少错误处理和重试机制 **原问题**: - 播放错误时没有重试机制 - 错误信息不够详细 **解决方案**: ```java // 添加重试机制 private void retryConnection(ChannelPlayerObj playerObj) { new Thread(() -> { try { Thread.sleep(2000); // 等待2秒后重试 if (getActivity() != null) { getActivity().runOnUiThread(() -> { try { IjkMediaPlayer ijkPlayer = playerObj.getIjkPlayer(); if (ijkPlayer != null) { ijkPlayer.reset(); ijkPlayer.setDataSource(playerObj.getCurrentPlayingUrl()); ijkPlayer.prepareAsync(); } } catch (Exception e) { LogUtil.e("重试连接失败: " + e.getMessage()); } }); } } catch (InterruptedException e) { LogUtil.e("重试连接被中断: " + e.getMessage()); } }).start(); } ``` ## 修复内容 ### 1. 优化播放器配置 - 增加缓冲区大小到1MB - 增加探测大小到50KB - 增加分析时间到100ms - 增加超时时间到5秒 - 启用包缓冲和音视频同步 - 禁用低延迟模式以提高稳定性 ### 2. 修复Surface创建时机 - 确保在Surface创建后再设置播放器显示 - 在Surface创建后再调用prepareAsync() ### 3. 添加重试机制 - 播放错误时自动重试 - 2秒延迟后重新连接 - 详细的错误日志记录 ### 4. 改进日志记录 - 添加详细的时间戳记录 - 记录每个步骤的耗时 - 便于问题定位和性能分析 ## 测试工具 ### 1. Python测试脚本 创建了 `test_flv_stream.py` 用于测试FLV流的可访问性: - HEAD请求测试 - GET请求测试 - FLV文件头验证 - 流式读取测试 ### 2. Android测试Activity 创建了两个测试Activity: - `FlvTestActivity`:完整的FLV测试界面 - `SimpleFlvTestActivity`:简化的测试界面 ## 建议 ### 1. 网络优化 - 确保设备网络连接稳定 - 考虑使用CDN加速 - 监控网络带宽使用 ### 2. 播放器优化 - 根据设备性能调整缓冲设置 - 考虑使用ExoPlayer作为备选方案 - 添加播放质量自适应 ### 3. 错误处理 - 添加网络状态监听 - 实现播放质量监控 - 提供用户友好的错误提示 ## 预期效果 修复后应该能够: 1. 正常播放FLV流 2. 减少播放延迟 3. 提高播放稳定性 4. 自动处理网络异常 5. 提供详细的调试信息 ## 验证方法 1. 运行测试脚本验证FLV流可访问性 2. 使用测试Activity验证播放功能 3. 查看日志确认播放器状态 4. 测试网络异常情况下的重试机制