FFmpeg开发笔记(二十七)解决APP无法访问ZLMediaKit的直播链接问题

news/2024/9/22 19:57:23/

上一篇文章介绍了如何通过ZLMediaKit实现视频推拉流,并使用VLC播放器验证视频直播地址。即使不用VLC播放器,直接在Qt工程的C++代码中调用FFmpeg的API,也能访问ZLMediaKit直播地址,并正常渲染视频画面。关于如何在Qt工程中引入FFmpeg,可参考《FFmpeg开发实战:从零基础到短视频上线》一书的“第11章  FFmpeg的桌面开发”。
《FFmpeg开发实战:从零基础到短视频上线》一书的“第12章  FFmpeg的移动开发”介绍了如何在手机APP上集成FFmpeg。根据该书的操作步骤,在APP工程的JNI代码中调用FFmpeg的API,也能正常播放ZLMediaKit直播画面。
但是如果手机APP不走FFmpeg,通过其他途径访问直播地址之时,却发现无法播放ZLMediaKitHLS直播地址http://124.***.***.***:8080/live/test/hls.m3u8。无论采用谷歌官方的ExoPlayer,还是采用微信小程序的video标签,都播放不了ZLMediaKitHLS视频。查看APP的报错日志,发现ExoPlayer扔出以下的错误信息:

E/ExoPlayerImplInternal: Playback errorcom.google.android.exoplayer2.ExoPlaybackException: Source errorat com.google.android.exoplayer2.ExoPlayerImplInternal.handleIoException(ExoPlayerImplInternal.java:641)at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:613)at android.os.Handler.dispatchMessage(Handler.java:105)at android.os.Looper.loopOnce(Looper.java:206)at android.os.Looper.loop(Looper.java:296)at android.os.HandlerThread.run(HandlerThread.java:67)Caused by: com.google.android.exoplayer2.upstream.HttpDataSource$InvalidResponseCodeException: Response code: 401at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.open(DefaultHttpDataSource.java:396)at com.google.android.exoplayer2.upstream.DefaultDataSource.open(DefaultDataSource.java:258)at com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:84)at com.google.android.exoplayer2.source.hls.HlsMediaChunk.prepareExtraction(HlsMediaChunk.java:495)at com.google.android.exoplayer2.source.hls.HlsMediaChunk.feedDataToExtractor(HlsMediaChunk.java:468)at com.google.android.exoplayer2.source.hls.HlsMediaChunk.loadMedia(HlsMediaChunk.java:437)at com.google.android.exoplayer2.source.hls.HlsMediaChunk.load(HlsMediaChunk.java:394)at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:412)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)at java.lang.Thread.run(Thread.java:930)

原来是流媒体服务端丢出了401错误,意思是没有权限拒绝访问。这个问题着实难搞,寻寻觅觅、反反复复,总也找不到为啥会没有权限,分明使用VLC播放器是可以正常播放的呀。
于是检查ZLMediaKit的源代码,发现ZLMediaKit内部对于HTTP地址增加了Cookie校验,原来这套校验规则适配了FFmpeg,却尚未适配ExoPlayer,也未适配小程序。问题代码位于ZLMediaKit源代码的src/Http/HttpFileManager.cpp里的accessFile函数,代码片段如下:

auto strongSession = weakSession.lock();
if (!strongSession) {// http客户端已经断开,不需要回复return;
}
if (!err_msg.empty()) {//文件鉴权失败StrCaseMap headerOut;if (cookie) {headerOut["Set-Cookie"] = cookie->getCookie(cookie->getAttach<HttpCookieAttachment>()._path);}cb(401, "text/html", headerOut, std::make_shared<HttpStringBody>(err_msg));return;
}

原来accessFile函数内部对于HTTP链接的Cookie校验失败时会固定返回401错误。那么修改HttpFileManager.cpp里的accessFile函数,把这里的401鉴权代码注释掉,并将修改后的代码文件上传到Linux服务器。
然后回到build目录运行make和make install命令重新编译安装ZLMediaKit,也就是依次执行下面命令。

kill -s 9 `ps -aux | grep MediaServer | awk '{print $2}'`
cd /usr/local/src/ZLMediaKit/build
make
make install

编译安装完毕,执行下面命令,重新启动MediaServer服务。

cd /usr/local/src/ZLMediaKit/release/linux/Debug
./MediaServer -d &

执行以下命令,将本地视频推流给ZLMediaKit

ffmpeg -re -stream_loop -1 -i "/usr/local/src/test/2018s.mp4" -vcodec h264 -f rtsp rtsp://127.0.0.1/live/test

然后在APP代码中使用ExoPlayer播放HLS地址http://124.***.***.***:8080/live/test/hls.m3u8,发现可以正常播放HLS视频了。接着使用真机调试微信小程序,发现通过video标签也能正常播放HLS视频了。更多详细的FFmpeg开发知识参见《FFmpeg开发实战:从零基础到短视频上线》一书。


http://www.ppmy.cn/news/1462037.html

相关文章

Python执行MYSQL SQL文件

很多情况下我们需要Python来执行SQL文件&#xff0c;但是一般库没有提供这些功能&#xff0c;直接执行经常会出错&#xff0c;这里分析各种情况下执行SQL语句的处理。如果你没有时间的话&#xff0c;直接跳转查看[第三点](#3. 包含DELIMITER的语句)。 准备工作 这里采用**mys…

Linux基础之僵尸进程与孤儿进程

目录 一、僵尸进程 1.1 什么是僵尸进程 1.2 为什么要有僵尸状态 1.3 观察我们的僵尸状态 1.4 关于僵尸进程的小Tip 二、孤儿进程 2.1 什么是孤儿进程 一、僵尸进程 1.1 什么是僵尸进程 在上一篇文章中&#xff0c;我们有提到过进程的死亡状态的概念&#xff0c;而我们的…

鸿蒙开发接口Ability框架:【ApplicationContext】

ApplicationContext ApplicationContext模块提供开发者应用级别的的上下文的能力&#xff0c;包括提供注册及取消注册应用内组件生命周期的监听接口。 说明&#xff1a; 开发前请熟悉鸿蒙开发指导文档&#xff1a; gitee.com/li-shizhen-skin/harmony-os/blob/master/README.m…

二次开发接口验证

二次开发接口验证通常涉及到几个关键步骤&#xff0c;以确保安全、有效且高效的数据交互。 这包括但不限于API密钥验证、请求参数验证、用户身份验证以及响应数据验证。 以下是一些基本的验证措施&#xff1a; 1. API密钥验证&#xff1a; 开发者需要从服务提供商那里获取一…

Spring中拦截器的使用

在Spring框架中&#xff0c;拦截器&#xff08;interceptor&#xff09;是一种用于拦截请求的组件&#xff0c;可以在请求处理的前后进行一些额外的处理。拦截器可以用于实现日志记录、权限验证、参数校验等功能。 在Spring中&#xff0c;拦截器是通过实现HandlerInterceptor接…

跨平台移动应用开发指南:打造跨越iOS和Android的移动应用

跨平台移动应用开发已经成为许多开发者的首选&#xff0c;因为它可以节省时间、成本和精力&#xff0c;同时使得应用能够覆盖更广泛的用户群体。本指南将介绍跨平台移动应用开发的基本概念、流行的跨平台框架以及一些最佳实践&#xff0c;帮助您快速入门并打造出高质量的跨平台…

springcloud+nocos从零开始

首先是去nacos官网下载最新的包&#xff1a;Nacos 快速开始 | Nacos win下启动命令&#xff1a;startup.cmd -m standalone 这样就可以访问你的nacos 了。 添加一个配置&#xff0c;记住你的 DataId,和Group名字。 创建一个pom项目&#xff0c;引入springCloud <?xml ve…

[muduo网络库]——使用muduo库搭建Echo服务器(剖析muduo网络库核心部分、设计思想)

在此之前&#xff0c;我们对于muduo库的每一类几乎都进行了逐行的分析&#xff0c;但是一个网络库的每个模块之间总是有千丝万缕的关系&#xff0c;所以可能有的地方还是有分析的不到位&#xff0c;所以从这一篇开始&#xff0c;我们从muduo的简单使用----搭建一个Echo服务器&a…