使用flutter_vlc_player播放RTSP视频时如何消除鱼眼效果?
解决Flutter VLC Player鱼眼视频矫正的几种思路
1. 直接用VLC内置滤镜(最简便)
flutter_vlc_player底层基于VLC,而VLC自带视频畸变矫正滤镜,完全不用自己写Shader。你可以在初始化播放器时添加VLC命令行参数,启用lenscorrection滤镜:
比如初始化时配置选项:
final player = VlcPlayerController.network( 'rtsp://your-stream-url', options: VlcPlayerOptions( advanced: VlcAdvancedOptions([ VlcAdvancedOption.networkCaching(500), // 启用鱼眼矫正滤镜,调整参数适配你的鱼眼程度 VlcAdvancedOption.videoFilter('lenscorrection'), VlcAdvancedOption.add('--lenscorrection-cx=0.5'), // 矫正中心X(范围0-1) VlcAdvancedOption.add('--lenscorrection-cy=0.5'), // 矫正中心Y(范围0-1) VlcAdvancedOption.add('--lenscorrection-k1=-0.3'), // 主矫正参数,负值为矫正鱼眼,按需调整 VlcAdvancedOption.add('--lenscorrection-k2=0'), // 次级矫正参数,一般设0即可 ]), ), );
不同鱼眼程度需要调整k1值,多试几个负数(比如-0.2到-0.5)就能找到最合适的效果。
2. 修复自定义Shader的应用问题
如果你坚持用Shader,大概率是应用方式不对——直接给VlcPlayer套ShaderMask无法正确作用于视频纹理帧。正确的做法是获取视频纹理ID,用CustomPaint手动渲染并叠加矫正Shader:
- 通过
VlcPlayerController的textureId拿到视频纹理; - 用
Texture承载纹理,在CustomPaint中对纹理应用矫正Shader:
示例代码结构:
Shader _fishEyeCorrectionShader() { return FragmentShader.fromFragmentShaderProgram(/* 你的矫正Shader程序 */) ..setFloat(0, MediaQuery.of(context).size.width) ..setFloat(1, MediaQuery.of(context).size.height); } @override Widget build(BuildContext context) { return CustomPaint( painter: _VideoTexturePainter( textureId: controller.textureId, correctionShader: _fishEyeCorrectionShader(), ), ); } class _VideoTexturePainter extends CustomPainter { final int textureId; final Shader correctionShader; _VideoTexturePainter({required this.textureId, required this.correctionShader}); @override void paint(Canvas canvas, Size size) { final rect = Rect.fromLTWH(0, 0, size.width, size.height); final paint = Paint()..shader = correctionShader; canvas.drawRect(rect, paint); // Shader核心逻辑是将极坐标转为笛卡尔坐标实现矫正: // 对每个像素点(x,y),计算到中心的距离r,修正x/y: // x_corrected = centerX + (x - centerX) * (1 + k1*r² + k2*r^4) // y_corrected = centerY + (y - centerY) * (1 + k1*r² + k2*r^4) } @override bool shouldRepaint(covariant _VideoTexturePainter oldDelegate) { return oldDelegate.textureId != textureId || oldDelegate.correctionShader != correctionShader; } }
对应的GLSL Shader代码示例:
uniform float width; uniform float height; uniform sampler2D u_texture; void main() { vec2 uv = gl_FragCoord.xy / vec2(width, height); vec2 center = vec2(0.5, 0.5); vec2 delta = uv - center; float r = length(delta); // 矫正参数,k1取负值 float k1 = -0.3; float factor = 1.0 + k1 * r * r; vec2 correctedUv = center + delta * factor; gl_FragColor = texture2D(u_texture, correctedUv); }
3. 流媒体服务器端预处理(性能最优)
如果前端处理导致卡顿,建议在推流前用FFmpeg对RTSP流做鱼眼矫正,再推给Flutter端:
ffmpeg -i rtsp://original-stream-url -vf "lenscorrection=cx=0.5:cy=0.5:k1=-0.3:k2=0" -c:v libx264 -preset fast -f rtsp rtsp://processed-stream-url
这样Flutter端直接播放处理后的流,完全不用额外开发。
内容的提问来源于stack exchange,提问作者jichang
相关产品推荐
相关产品推荐

