近期由于流媒体服务人员离职的原因,从事C#工作的我*分析开源流媒体服务CRtmpServer。一切从零开始,从google下载了源码在环境搭建编译出现链接库等各种问题不断出现,在度娘的帮助下和还不算笨的我终于成功将环境源码搭好并编译通过并布属至Linux服务器。成功布属后,应用测试一切正常,但突然发现通过FFMPEG截图出现异常,同时XSPlit也无法正常实现推流。
FFMPEG截图异常为:
HandShake: client signature does not match!
rtmp server sent error
WriteN, RTMP send error 10054 (42 bytes)
RTMP_ReadPacket, failed to read RTMP packet header
苦查度娘无果,最后经过长达一周的断点调试,由于过程跳来跳去得盯得紧屏幕又不能分神一次下来眼泪水都出来了,几经周折反复比较Flash与XSplit与FFMPEG请求的区别。终于将问题锁定于以下一段Switch。
switch ((int32_t) startTime) { case -2: //live or recorded { bool linked = false; //7. try to link to live stream if (!TryLinkToLiveStream(pFrom, VH_SI(request), streamName, linked)) { FATAL("Unable to link streams"); return false; } if (linked) return true; //8. try to link to file stream if (!TryLinkToFileStream(pFrom, VH_SI(request), metadata, streamName, startTime, length, linked)) { FATAL("Unable to link streams"); return false; } if (linked) return true; //9. Ok, no live/file stream. Just wait for the live stream now... WARN("We are going to wait for the live stream `%s`", STR(streamName)); BaseOutNetRTMPStream * pBaseOutNetRTMPStream = pFrom->CreateONS( VH_SI(request), streamName, ST_IN_NET_RTMP); request["waitForLiveStream"] = (bool)true; request["streamName"] = streamName; return pBaseOutNetRTMPStream != NULL; } case -1: //only live { bool linked = false; //10. try to link to live stream if (!TryLinkToLiveStream(pFrom, VH_SI(request), streamName, linked)) { FATAL("Unable to link streams"); return false; } if (linked) return true; //11. Ok, no live/file stream. Just wait for the live stream now... WARN("We are going to wait for the live stream `%s`", STR(streamName)); BaseOutNetRTMPStream * pBaseOutNetRTMPStream = pFrom->CreateONS( VH_SI(request), streamName, ST_IN_NET_RTMP); request["waitForLiveStream"] = (bool)true; request["streamName"] = streamName; return pBaseOutNetRTMPStream != NULL; } default: { //12. Perform little adjustment on metadata if (metadata[META_MEDIA_TYPE] == MEDIA_TYPE_LIVE_OR_FLV) { metadata[META_MEDIA_TYPE] = MEDIA_TYPE_FLV; } //13. try to link to file stream bool linked = false; if (!TryLinkToFileStream(pFrom, VH_SI(request), metadata, streamName, startTime, length, linked)) { FATAL("Unable to link streams"); return false; } return linked; } }
Flash与FFMPEG的区别是Flash进入的是-1也就是请求Live方式,而FFMPEG与XSPLIT请求的是0将进入default,看逻辑是请求录制源。然而直播是按Live方式的,所以自然尝试链接流媒体文件时(TryLinkToFileStream)出现异常也不觉奇怪了。
原因知道了那么就简单了,我的方法是直接将Live or Recorded逻辑做为Default处理。
运行,调试,一丝笑意,通过。