美文网首页直播技术
移动端直播开发(四)播放与弹幕评论

移动端直播开发(四)播放与弹幕评论

作者: 前世小书童 | 来源:发表于2017-02-23 20:07 被阅读899次

写在前面的话

上一篇已经介绍了关于RTMP推流相关的知识,那么推完流后视频服务器就会对推流进行转发,那么这一篇主要就是介绍下,关于移动端播放与弹幕评论相关的知识。

一.播放

关于播放其实一般情况我们都是使用第三方的播放库,因为这些库相对来说支持各种不同的协议比如RTMP,HLS或者其他的视频协议,那我们这里就使用Bilibili开发并开源的IJKPlayer播放器,关于這方面更多的讲解可以参考之前写的文章IJKPlayer初识-编译与使用

我们只需要把视频转发的地址设置进去就好了

如下

图1 直播播放

由于录制视频再转GIF不太方便,所以就单独上一张图了,明白是什么意思就好。

其实很多直播平台也是用的IJKPlayer做的播放器,比如斗鱼呀等等

对于现在的直播来说,弹幕评论也是直播平台中很重要的一部分,所以接下来我们来探究下关于移动端关于弹幕评论的实现

二.弹幕评论

对于弹幕评论,其实客户端我们可以想到的方法就是轮询来不断的获取最新的评论数据,但是可想而知不停的网络请求访问,会对整个客户端的性能带来一定的问题,而且也会导致对于手机电量的消耗增大,所以我们得想出另外的方案来解决这个问题,自然就是参考现在比较成熟的PC网站是如何实现这部分的需求的,其实现在有部分的网站已经在使用WebSocket来实现实时弹幕的效果了,当然在我们移动端也是可以使用WebScoket的,所以我们就用WebScoket方案来实现弹幕评论

工欲善其事必先利其器,所以我们先了解下什么是WebScoket

WebScoket

WebSocket协议是一种建立在TCP连接基础上的全双工通信的协议,同http一样通过TCP来传输数据,但是它和http最大的不同有两点:1.WebSocket是一种双向通信协议,在建立连接后,WebSocket服务器和Browser/UA都能主动的向对方发送或接收数据,就像Socket一样,不同的是WebSocket是一种建立在Web基础上的一种简单模拟Socket的协议;2.WebSocket需要通过握手连接,类似于TCP它也需要客户端和服务器端进行握手连接,连接成功后才能相互通信。

协议内容组成如下

图2 WebScoket协议内容

WebSocket按上面图中协议规则进行传输,上图称为一个数据帧。

  • FIN,共1位,标记消息是否是最后1帧,1个消息由1个或多个数据帧构成,若消息由1帧构成,起始帧就是结束帧。

  • RSV1,RSV2,RSV3,各1位,预留位,用于自定义扩展。如果没有扩展,各位值为0;如果定义了扩展,即为非0值。如果接收的帧中此处为非0,但是扩展中却没有该值的定义,那么关闭连接。

  • OPCODE,共4位,帧类型,分为控制帧和非控制帧。如果接收到未知帧,接收端必须关闭连接。

    WebSocket的控制帧有3种,关闭帧、Ping帧、Pong帧,关闭帧很好理解,客户端如果收到关闭帧直接关闭连接即可,当然客户端也可以发送关闭帧给服务器端。而Ping帧和Pong帧则是WebSocket的心跳检测,用于保证客户端是在线的,一般来说,只有服务端给客户端发送Ping帧,然后客户端发送Pong帧进行回应,表示自己还在线,可以进行后续通信。

  • MASK,共1位,掩码位,表示帧中的数据是否经过加密,客户端发出的数据帧需要经过掩码处理,这个值都是1。如果值是1,那么Masking-key域的数据就是掩码秘钥,用于解码PayloadData,否则Masking-key长度为0

  • Payload len,7位或者7+16位或者7+64位,表示数据帧中数据大小,这里有好几种情况。

    如果值为0-125,那么该值就是payload data的真实长度。
    如果值为126,那么该7位后面紧跟着的2个字节就是payload data的真实长度。
    如果值为127,那么该7位后面紧跟着的8个字节就是payload data的真实长度。
    长度遵循一个原则,就是用最少的字节表示长度,举个例子,当payload data的真实长度是124时,在0-125之间,必须用7位表示;不允许将这7位表示成126或者127,然后后面用2个字节或者8个字节表示124,这样做就违反了原则。

  • Masking-key ,0或者4个字节,当MASK位为1时,4个字节,否则0个字节。如果MASK值为1,则发出去的数据需要经过加密处理

  • Payload data,其大小是(x+y)个字节,x是Extension data,即扩展数据,y是Application data,即程序数据,扩展数据可能为0。 如果扩展数据不为0,必须提前进行协商,规定其长度,否则是不合法的数据帧。

以上是WebSocket数据传输的帧内容,大致了解即可。

对于WebSocket和前面说的RTMP一样也是有握手协议的过程,接下来我们就看一下WebSocket握手协议

客户端发送get请求协议升级

GET /chat HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key:dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat,superchat
Sec-WebSocket-Version: 13

该请求会在请求头上带上WebSocket的版本号,这里是13,以及客户端随机生成的Sec-WebSocket-Key,服务器端收到后根据这个key进行一些处理,返回一个Sec-WebSocket-Accept的值给客户端。

服务端返回同意升级到WebSocket协议

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept:s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat

收到响应后,响应头中包含Sec-WebSocket-Accept值,该值表示服务器端同意握手,值的计算方式如下:

$(Sec-WebSocket-Accept)=BASE64(SHA1($(Sec-WebSocket-Key)+"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"))

客户端得到该值后,对本地的Sec-WebSocket-Key进行同样的编码,然后对比,如果相同则可以进行后续处理。

关于WebSocket协议,一般来说,如果是通过https协议开始升级而来的,那么一般是wss://开头,如果是http协议开始升级而来的,那么一般是ws://开头

WebScoket实现弹幕效果

前面说了相关协议的东西,那么接下来就是实现具体的效果了,对于Android平台,我们可以Java-WebSocket库来实现WebSocket通信,当然除了这个还可以选择其他的库,我这里选择Java-WebSocket来实现我们的功能了。

WebScoket服务器搭建

对于WebScoket服务器搭建,可以使用Java API javax.websocket包中的WebSocket相关类(注意Java API只实现了标准的RFC 6455(JSR256),如果你非要选择其它早期草案则需要用Java-WebSocket来实现,在Java-WebSocket中连接协议“Draft_17”就是标准的RFC 6455(JSR256),另外要使用Java API javax.websocket包中的WebSocket相关类要求JDK7及以上,Tomcat 7.0.49及以上):

代码如下

@ServerEndpoint(value = "/websocket/{user}")
public class ChatServerEndpoint {

    private static Set<Session> sessions = new HashSet<Session>();
    private Session session;

    @OnOpen
    public void open(Session session, @PathParam(value = "user") String user) {

        this.session = session;
        sessions.add(this.session);

        sendToAll(session.getRequestURI() + "进入房间");

        System.out.println(session.getRequestURI() + " 进入房间");
    }

    @OnClose
    public void close() {

        sessions.remove(session);

        sendToAll(session.getRequestURI() + " 离开房间");

        System.out.println(session.getRequestURI() + " 离开房间");
    }

    @OnMessage
    public void message(String message) {

        sendToAll("[" + session.getRequestURI() + "]" + message);

        System.out.println("[" + session.getRequestURI() + "]" + message);
    }

    private void sendToAll(String text) {

        for (Session client : sessions) {
            synchronized (client) {
                client.getAsyncRemote().sendText(text);
            }
        }
    }

}

这里服务器端的代码主要是消息转发功能,进入,离开,以及用户发送信息都会转发给连接的客户端。

启动tomcat就可以用Android客户端来连接进行聊天、接收推送了。

Android端创建

首先添加Java-WebSocket的依赖如下

compile 'org.java-websocket:Java-WebSocket:1.3.0'

接下来就可以创建一个WebSockeClient

WebSocketClient client = new WebSocketClient(new URI(""), new Draft_17()) {
    @Override
    public void onOpen(ServerHandshake handshakedata) {
        Log.e("hxy", "已经连接到服务器【" + getURI() + "】");
    }

    @Override
    public void onMessage(String message) {
        Log.e("hxy", "获取到服务器信息【" + message + "】");
    }

    @Override
    public void onClose(int code, String reason, boolean remote) {
        Log.e("hxy", "断开服务器连接【" + getURI() + ",状态码: " + code + ",断开原因:" + reason + "】");
    }

    @Override
    public void onError(Exception ex) {
        Log.e("hxy", "连接发生了异常【异常原因:" + ex + "】");
    }
};  
client.connect();

这里我们只有设置前面搭建的服务器端的地址即可,然后就可以监听到连接,断开,异常等信息,同时也可以监听到服务器发出的信息。

同样我们也可以向服务器发送信息,代码如下

client.send("message from client");

通过这样就可以实现服务器与客户端的双向通信了

运行如下:

图3 webSocket通讯

可以看到这里客户端A连接服务器端,并发生消息,服务器端转发连接信息与来自客户端A的信息,客户端A接收后将信息显示出来,然后用另外的客户端B进行连接发送信息,客户端A同样可以接收到后将信息显示出来。

所以这里就实现了WebSocket相关的双向通信了,

至于怎么弹幕,有了数据,弹幕只是表现形式咯,这个实现比较简单就不做说明了,其实可以使用同样Bilibili开发并开源的DanmakuFlameMaster

写在后面的话

那么到这里就完成了移动直播相关的基本的问题了,我这边更加着重于对于原理的讲解,而不是把代码贴出来简单的概述而过,跟着这些原理一步一步研究出来显然会对自己提升更大,至于视频直播的滤镜问题,可以参考我写的滤镜系列文章,当然我这里仅仅是实现了直播的整套流程,但是对于直播其实还有很多的问题,这里就不做过多的研究了,有兴趣的朋友可以进行进一步的研究,peace~~~

相关文章

  • 移动端直播开发(四)播放与弹幕评论

    写在前面的话 上一篇已经介绍了关于RTMP推流相关的知识,那么推完流后视频服务器就会对推流进行转发,那么这一篇主要...

  • 拉流部分

    直播系列的最后一部分,在移动端进行播放。有需要的请看之前的两部分: 搭建服务端 推流部分 在移动端进行播放,我选择...

  • 网易云音乐、酷狗音乐、QQ音乐、虾米音乐评论区对比分析

    本文从布局架构和内容分析两个方面对国内四个著名移动端音乐播放器的评论区进行了比较 评论入口显示 网易云音乐的评论入...

  • Android直播之基本概念(二)

    1.直播的采集端(推流端)和播放端 直播的流程: 播放流程: 获取流–>解码–>播放录制播放路程: 录制音频视频–...

  • H5直播Video.js

    最近做了一个移动端H5简易版直播页,只有直播功能,后期再添加弹幕和礼物,要求是在微信中,虽然没有涉及到录制直播这方...

  • Think-PHP3.2使用超酷播放器使用弹幕

    注意,这里的直播放仅是说弹幕采用直播的形式,不是指视频直播 普通的视频弹幕:该插件因为为了简单化使用,所以没有使用...

  • H5移动端直播的要点

    在移动端,基于浏览器环境与微信及QQ的软件内部环境标准实现直播功能及在其基础上的附加功能(例如,加上弹幕及其他覆盖...

  • 直播项目---弹幕问题

    抽空来总结一下前段时间搞的直播中弹幕问题。有1.弹幕移动的移速问题 2.弹幕移动重叠问题的解决 3.大量弹幕情况利...

  • 小窗播放基础图层展示和处理笔记

    需求:直播观众端退出直播间时候,进行小窗播放小窗能够随手指长按拖拽移动(以下用红色图层的拖拽实现)小窗上的按钮能够...

  • 移动端开发新趋势Flutter

    移动端开发新趋势Flutter移动端开发新趋势Flutter

网友评论

    本文标题:移动端直播开发(四)播放与弹幕评论

    本文链接:https://www.haomeiwen.com/subject/uegewttx.html