Html5之webcoekt播放JPEG图片流


Posted in HTML / CSS onSeptember 22, 2020

一、简介

既然webcoekt是基于tcp连接的,理论上讲所有的浏览器是可以私有协议处理二进制的,如果我们需要播放视频,我们可以将视频数据在后端解码后直接将图片推送到webcoekt前端,然后前端通过websocket接收图片然后将图片显示到img或canvas中即可,当然这个是我自己设想的,也是应该可以做的到了,做到如下需要以下技术支持:

  • 后端直接ffmpeg转码为jpeg图片流
  • 后端定制播放协议包括基本指令如play、stop、pause、faster、slower
  • 后端需要提供websocket支持发送图片流到前端
  • 前端需要接受图片流并显示出来

后端ffmpeg解码这里就不说明了,我有很多库,需要的单独联系我购买,前端的显示jpg流,这里要借助前端显示图片放的做法,使用图片base64数据!前端HTML显示二进制jpeg图片:图片流=>二进制转image的base64编码=>设置到img的src中,如前端代码

<body>
    <img id="player" style="width:704px;height:576px"/>
</body>

二进制通过arraybuffer转base64

function arrayBufferToBase64(buffer) {
        var binary = '';
        var bytes = new Uint8Array(buffer);
        var len = bytes.byteLength;
        for (var i = 0; i < len; i++) {
            binary += String.fromCharCode(bytes[i]);
        }
        return window.btoa(binary);
    }

最后显示:

var player = document.getElementById('player');
      var url= arrayBufferToBase64(data);
      player.src='data:image/jpeg;base64,'+url;

当然,还有其他的方式:

var wsCtrl = new WebSocket("ws://127.0.0.1/ctrl/");
//Establish channel code
....
var wsVideo = new WebSocket("ws://127.0.0.1/video/channel1");
wsVideo.onmessage = function(evt)
{
   //Method 1
   document.getElementById("img1").src = URL.createObjectURL(evt.data);
   
   //Method 2
   var read = new FileReader();
   read.onload = function(e)
   {
      document.getElementById("img2").src = e.target.result;
   }
   read.readAsDataURL(evt.data);
}

ws.onmessage = function(evt) {
    if(typeof(evt.data)=="string"){
        //textHandler(JSON.parse(evt.data));
    }else{
        var reader = new FileReader();
        reader.onload = function(evt){
            if(evt.target.readyState == FileReader.DONE){
                var url = evt.target.result;
                alert(url);
                var img = document.getElementById("imgDiv");
                img.innerHTML = "<img src = "+url+" />";
            }
        }
        reader.readAsDataURL(evt.data);
    }
};

关于c++的websocket开源工程:websocketpp、QWebSocketServer

二、websocket播放图片流

多说无益,还不如痛痛快快的来一把,为了减低复杂度,我用java的websocket来实现图片流的发送(当然c++的库我也一个实战项目中用过的名为WebSocket的封装的dll工程项目,需要的自行私下购买源码),前端使用一个img标签展示图片,这里说明一下,后台模拟发送图片(这里仅仅是图片,不是流,如果是流直接连续不断发送即可需要ffmpeg转码)

首先前端的代码如下所示:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>websocket显示二进制图片流</title>
        <style type="text/css">
        </style>
    </head>
    <script src="jquery.min.js"></script>
    <script>
    $(document).ready(function(){
        $("#send").click(function(){
          //var content = $("#content").val();
          $.ajax({
              url: "/test/send",
              data: {
                 //content: content
                 content: ""
              },
              success: function( result ) {
                  console.log("请求成功!");
              }
            });
      });
    });
    </script>
    <body>
        <h1>WebSocket播放图片</h1>
        <img id="player" style="width:500px;height:400px"/><br/>
        <button id="send">请求图片</button>
    </body>
    <script type="application/javascript">
        var websocket = {
            send: function (str) {
            }
        };
        window.onload = function () {
            if (!'WebSocket' in window) return;
            webSocketInit();
        };
        function webSocketInit() {
            // 连接到服务端端点
            websocket = new WebSocket("ws://127.0.0.1:8080/image/show");
            // 成功建立连接
            websocket.onopen = function () {
                console.log("成功连接到服务器");
                websocket.send("成功连接到服务器");
            };
            // 接收到消息
            websocket.onmessage = function (event) {
                // 文本数据包
                if(typeof(event.data)=="string"){
                    // JSON.parse(evt.data)
                    console.log("收到服务端发送的消息:" + event.data);
                // 图片数据包Blob
                }else{
                    var reader = new FileReader();
                    reader.onload = function(evt){
                        if(evt.target.readyState == FileReader.DONE){
                            // base64数据
                            var url = evt.target.result;
                            document.getElementById("player").src = url;
                        }
                    }
                    reader.readAsDataURL(event.data);
                }
            };
            // 连接发生错误
            websocket.onerror = function () {
                console.log("WebSocket连接发生错误");
            };
            // 连接关闭
            websocket.onclose = function () {
                console.log("WebSocket连接关闭");
            };
            // 监听窗口关闭事件,当窗口关闭时,主动关闭websocket连接
            window.onbeforeunload = function () {
                websocket.close()
            };
        }
    </script>
</html>

每次点击发送的时候就向后台请求一张图,后台将改图发送出去(我简单的使用websocket群发,可以使用websocket的可变参数将websocket和http关联起来,这个应该很容易我这里不再赘述,不了解的进群讨论)

package com.easystudy.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Random;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.easystudy.websocket.ImgEndPoint;

/**
 * @文件名称: TestController.java
 * @功能描述: 图片流请求请求发送接口(websocket发送图片到web端)
 * @版权信息:  www.easystudy.com
 * @技术交流:  961179337(QQ群)
 * @编写作者:  lixx2048@163.com
 * @联系方式:  941415509(QQ)
 * @开发日期:  2020年9月21日
 * @历史版本: V1.0 
 * @备注信息:
 */
@RestController
@RequestMapping("/test")
public class TestController {
    
    /**
     * @功能描述: 发送请求接口
     * @版权信息:  www.easystudy.com
     * @编写作者:  lixx2048@163.com
     * @开发日期:  2020年9月21日
     * @备注信息:
     */
    @SuppressWarnings("unused")
    @GetMapping("/send")
    public String reponseMsgToClient(@RequestParam(name="content", required = true)String content) throws Exception{
        System.out.println("开始发送图片数据");
        
        // 随机选择一张图片发送
        int index = new Random().nextInt(4) + 1;
        String imgName = index + ".jpg";
        
        // 判断图片是否存在
        URL url = getClass().getClassLoader().getResource(imgName);
        File file = new File(url.getFile());
        if (!file.exists()) {
            return "未找到图片!";
        }
        
        // 创建输入图片流
        InputStream in = new FileInputStream(file);
        if (null == in) {
            return "打开文件失败!";
        }
        
        // 读取图片数据
        int size = (int)file.length();
        byte[] buffer = new byte[ size];
        int count = in.read(buffer, 0, size);    
        System.out.println("文件长度:" + size + ", 读取长度:" + count);
        
        // 发送图片数据(理论上讲应该只发对端连接的)
        ImgEndPoint.fanoutMessage(buffer);
        
        // 关闭文件流
        try {
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        // 接口响应
        return "消息【" +content+ "】发送成功!";
    }
}

我这里多一句嘴,如果是音视频应用的录像播放,这里可以使用websocket传输图片流,然后通过计算发送定点的图片流数据到前端来实现自定义的播放器功能(海康萤石云使用的就是websocket播放录像流的,做法类似)

播放效果如下:

Html5之webcoekt播放JPEG图片流

Html5之webcoekt播放JPEG图片流

到此这篇关于Html5之webcoekt播放JPEG图片流的文章就介绍到这了,更多相关Html5播放JPEG图片流内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章,希望大家以后多多支持三水点靠木!

HTML / CSS 相关文章推荐
CSS3制作精致的照片墙特效
Jun 07 HTML / CSS
css3 给页面加个半圆形导航条主要利用旋转和倾斜样式
Feb 10 HTML / CSS
CSS3实现同时执行倾斜和旋转的动画效果
Oct 27 HTML / CSS
纯CSS3实现漂亮的input输入框动画样式库(Text input love)
Dec 29 HTML / CSS
CSS3实现缺角矩形,折角矩形以及缺角边框
Dec 20 HTML / CSS
HTML5移动端开发遇见的东西
Oct 11 HTML / CSS
只要五步 就可以用HTML5/CSS3快速制作便签贴特效(图)
Jun 04 HTML / CSS
html5基础标签(html5视频标签 html5新标签用法)
Dec 30 HTML / CSS
HTML5中新标签和常用标签详解
Mar 07 HTML / CSS
HTML5单页面手势滑屏切换原理
Mar 21 HTML / CSS
Html5 webview元素定位工具的实现
Aug 07 HTML / CSS
几款流行的HTML5 UI框架比较(小结)
Apr 08 HTML / CSS
如何在Canvas上的图形/图像绑定事件监听的实现
Sep 16 #HTML / CSS
canvas 绘图时位置偏离的问题解决
Sep 16 #HTML / CSS
关于canvas.toDataURL 在iOS运行失败的问题解决
Sep 16 #HTML / CSS
canvas绘制图片drawImage使用方法
Sep 15 #HTML / CSS
HTML5中外部浏览器唤起微信分享功能的代码
Sep 15 #HTML / CSS
浅析HTML5 Landmark
Sep 11 #HTML / CSS
详解HTML5中CSS外观属性
Sep 10 #HTML / CSS
You might like
php中的实现trim函数代码
2007/03/19 PHP
PHP内置的Math函数效率测试
2014/12/01 PHP
浅谈Yii乐观锁的使用及原理
2017/07/25 PHP
php对象工厂类完整示例
2018/08/09 PHP
使用Git实现Laravel项目的自动化部署
2019/11/24 PHP
使用Entrust扩展包在laravel 中实现RBAC的功能
2020/03/16 PHP
国外Lightbox v2.03.3 最新版 下载
2007/10/17 Javascript
javascript陷阱 一不小心你就中招了(字符运算)
2013/11/10 Javascript
关于onchange事件在IE和FF下的表现及解决方法
2014/03/08 Javascript
用C/C++来实现 Node.js 的模块(二)
2014/09/24 Javascript
javascript中replace( )方法的使用
2015/04/24 Javascript
jQuery实现信息提示框(带有圆角框与动画)效果
2015/08/07 Javascript
js创建数组的简单方法
2016/07/27 Javascript
js表单元素checked、radio被选中的几种方法(详解)
2016/08/22 Javascript
Node.js 异步异常的处理与domain模块解析
2017/05/10 Javascript
vue+vuecli+webpack中使用mockjs模拟后端数据的示例
2017/10/24 Javascript
js实现登录时记住密码的方法分析
2020/04/05 Javascript
vue-cli3项目打包后自动化部署到服务器的方法
2020/09/16 Javascript
简单的编程0基础下Python入门指引
2015/04/01 Python
从零开始学Python第八周:详解网络编程基础(socket)
2016/12/14 Python
Python学习之用pygal画世界地图实例
2017/12/07 Python
PyTorch快速搭建神经网络及其保存提取方法详解
2018/04/28 Python
python列表每个元素同增同减和列表元素去空格的实例
2019/07/20 Python
Tensorflow之MNIST CNN实现并保存、加载模型
2020/06/17 Python
CSS实现雨滴动画效果的实例代码
2019/10/08 HTML / CSS
HTML5实现获取地理位置信息并定位功能
2015/04/25 HTML / CSS
英国在线照明超市:Castlegate Lights
2019/10/30 全球购物
J2EE面试题大全
2016/08/06 面试题
青年教师师德演讲稿
2014/08/26 职场文书
争先创优活动总结
2014/08/27 职场文书
幼儿园感谢信
2015/01/21 职场文书
办公室岗位职责范本
2015/04/11 职场文书
Python编写可视化界面的全过程(Python+PyCharm+PyQt)
2021/05/17 Python
Python竟然能剪辑视频
2021/05/25 Python
雄兵连:第三季先行图公开,天使恶魔联合,银河之力的新力量
2021/06/11 国漫
MySQL中一条SQL查询语句是如何执行的
2022/04/08 MySQL