Hls协议工作主要分为两大块,一块是http协议,一块是ts码流的封装。前面已经成功完成了ts码流的封装,下面的重点工作就是完成http协议的实现。
我是C#的忠实粉丝,所以采用了HttpListener类来实现。
HttpListener listerner = new HttpListener
{
AuthenticationSchemes = AuthenticationSchemes.Anonymous
};
listerner.Prefixes.Add("http://192.168.150.130:8080/");
listerner.Start();
这里卡了我好几个小时,直到今天早上醒的早,想来试一下。6点就起来了,笨鸟先飞的鸟儿运气不会差。
在下面的时间,终于找到了原因。
我存在的问题是,在本机可以建立tcp连接,但是换了其他电脑,完全不行,另外,我把程序放到win7下面运行,又是正常的。
就是win10的这个在搞鬼。关了之后,一切正常。
这个方式,可以实现应答字符串了,但是2进制还需要研究。
HttpListenerContext httpListenerContext = listerner.GetContext();
Console.WriteLine("url ={0}", httpListenerContext.Request.RawUrl);
if(httpListenerContext.Request.RawUrl.Contains("m3u8"))
{
httpListenerContext.Response.StatusCode = 200;
using (StreamWriter writer = new StreamWriter(httpListenerContext.Response.OutputStream))
{
writer.WriteLine(Getextm3u());
}
}
研究api中,如何应答ts流的2进制数据。
在微软的官网找到了实例,开心。
https://docs.microsoft.com/zh-cn/dotnet/api/system.net.httplistener?view=netframework-4.7.2
技术工作基本完善,回公司开始做集成测试。
我感觉我运气特别好,现在可以实现在移动端播放hls流了。
采用的原生的h5播放,示例如下:
<!DOCTYPE html>
<html>
<head>
<style>
video {
width: 880px;
height: 880px;
border: 2px solid #000000;
object-fit: fill;
margin-top: 10px;
}
</style>
</head>
<body>
欢迎大家关注我的博客!
<div style="text-align:center;">
<button onclick="playPause()">播放/暂停</button>
<button onclick="makeBig()">大</button>
<button onclick="makeNormal()">中</button>
<button onclick="makeSmall()">小</button>
<br />
<video id="video1" webkit-playsinline='true' playsinline='true'>
<source src="http://192.168.31.188:8080/a.m3u8" controls" />
你的浏览器不支持html5的video标签
</video>
</div>
<script type="text/javascript">
var myVideo=document.getElementById("video1");
function playPause(){
if (myVideo.paused)
myVideo.play();
else
myVideo.pause();
}
function makeBig(){
myVideo.width=560;
}
function makeSmall(){
myVideo.width=320;
}
function makeNormal(){
myVideo.width=420;
}
</script>
</body>
</html>
有几个重点问题,解决了好久:
1、ts流的封装,一定要在每一帧之前,加上0x00,0x00,0x00,0x01,0x09,0xF0 表示一帧的开始,不然手机端无法播放。这个问题查了我好几个小时。
2、m3u8的格式的应答序号,EXT-X-MEDIA-SEQUENCE 在文件相同的时候,一定要保持一致,不然手机端也会出问题。
上述两个问题解决之后,我就成功的在手机端完成了播放。运气真的很好。
另外不得不说,hls的时延真的不行,所以在对时延比较敏感的场合,完全不合适。可以采用websocket直接推送fmp4的码流。