我目前面临live555的问题。
我为我的项目编写了一个Windows DLL,这个DLL公开了一个非常简单的API来轻松启动RTSP客户端。 Unity程序加载DLL,然后使用API接收帧。
暴露的两个主要功能是:
bool startRTSP(bool isTCP);
bool stopRTSP();
由于Live555库的性质,我无法在Unity线程中启动RTSP。所以我在调用startRTSP时创建了一个新线程,并且通过一些回调将帧发送到unity。
但是,为了能够从外部线程(调用stopRTSP的统一线程)停止RTSP,我正在使用eventLoopWatchVariable。例如,这是RTSP事件循环的启动方式:
env->taskScheduler().doEventLoop(&eventLoopWatchVariable);
调用stop函数时,来自unity线程的eventLoopWatchVariable设置为1。关闭事件循环。
在此事件循环退出后,调用清理函数:
delete scheduler;
env->reclaim();
我期待thoose功能通过RTSP客户端并关闭它们。 (例如,将TEARDOWN命令发送到服务器)
但他们显然没有,客户永远不会被摧毁!
我怀疑它会导致同一个流的reconexion问题。 (发送SETUP,DESCRIBE和PLAY命令并收到响应,但没有数据到来)使用VLC或mplayer我可以看到服务器仍在流式传输,因此这不是服务器问题。
当eventLoopWatchVariable设置为1时,如何让live555关闭RTSPClient及其子会话?
如果eventLoop不再运行,我无法将TEARDOWN命令发送到服务器。所以我现在有点迷失最好的方法。
如果有人对此有所了解,我很乐意听到它!
提前致谢。
如果eventLoop不再运行,我无法将TEARDOWN命令发送到服务器。
这是不精确的,需要mainloop来接收不发送消息的消息。
为了在mainloop之后和释放环境之前正确关闭RTSP客户端连接,您可以这样继续:
// wait for stop event
env->taskScheduler().doEventLoop(&eventLoopWatchVariable);
// send tear TEARDOWN
client->sendTeardownCommand(session, NULL);
// close subsession & session
Medium::close(session);
// close RTSP client
Medium::close(client);
// free environment & scheduler
env->reclaim();
delete scheduler;
你也可以等待TEARDOWN回答,给sendTeardownCommand回调并再次运行doEventLoop。
以下是完全关闭rtsp客户端的正确方法。这个答案假设您使用以下程序作为rtsp客户端的基础:testProgs / testRTSPClient.cpp(与live555捆绑在一起)。
首先将openURL()修改为一些如何将“RTSPClient * rtspClient”返回给调用者。然后使用此示例(从testRTSPClient.cpp中的main()继续):
RTSPClient* rtspClient = openURL(*env, argv[0], argv[1]);
// All subsequent activity takes place within the event loop:
env->taskScheduler().doEventLoop(&eventLoopWatchVariable);
//... do whatever stuff you want to do in the background...
//start this code when you want to stop the rtsp client
eventLoopWatchVariable = 1;
//run this code for each rtspClient that exists
StreamClientState& scs = ((ourRTSPClient*)rtspClient)->scs;
rtspClient->sendTeardownCommand(*scs.session, NULL);
Medium::close(client->rtspClient);
//end code segment
env->reclaim();
env = NULL;
delete scheduler;
scheduler = NULL;