概述
本章主要讲解实际工作中遇到的问题,以及如何解决并实现,下面是音视频开发的常用工具,下载地址就不贴了。
VLC media player 视频流播放工具
MediaInfo 视频信息查看工具
开发人员:app(负责开发板),java(负责服务器,进行编解码)
一.通过海康sdk获取视频流
海康提供的sdk录像功能,然后保存到sd卡中,当客户端有人想看这个视频时,去sd卡中拿视频
实现步骤:
1.当开发板生成视频,将视频路径以及设备id信息通知后端服务器,服务器将数据展示在web界面中.
2.当web界面,有人想看某个视频,将视频路径传到服务器,服务器通过websocket和开发板通信(这里之所以用websocket,是因为板子没有公网ip,所以它可以访问服务器,因为nat或其他技术,但是服务器无法直接访问这块板子,所以需要,板子一上电,就和服务器建立一个双通道的websocket,这样双方就可以交换数据了),根据协议,封装数据报,并发送。
3,开发板根据和服务器协商好的协议(类似于网络协议,便于双方知道对方想干什么),知道服务器要看视频,然后解析视频路径,然后去sd卡中获取,然后将文件流(stream)传到服务器,服务器接收到流,在返回给web客户端。
遇到的问题:
1.浏览器如何播放视频?
2.sd卡中保存的视频的封装格式是MPEG-PS,普通播放器无法播放,需要转码
问题1:浏览器如何播放视频?
1.前端可以拿到文件流,具体就是byte数组,然后转成base64,赋值给vedio标签,但是这样有个问题如果视频较小,这么做可以,但是如果视频是几十兆的这种,时间会比较久,低配的电脑,可能浏览器会出现卡死的情况,所以这种方案即便可以,但是用户体验也不是太好,因为base64转码会比原文件,多出三分之一的大小,这种实现的最大弊端就是,由于是通过文件流传输,从开发板到服务器,再从服务器到web,耗时太久,网络不是很好的话,耗时还会增加,所以这种方式肯定是有问题的。
**2.开发板将文件流传给服务器,服务器将流上传至文件服务器,然后返回一个公网可以访问的url,然后将这个视频和url做一个映射(map),别人在看这个视频,就可以通过映射关系,拿到url,将url返回到web,vedio可以直接播放,这种方式有个好处,多个人看一个视频的时候,视频只需要传递一次,就可以,至于为什么开发板生成视频后就上传到文件服务器,因为一些原因(板子有sd卡,视频生成是因为发生了故障xxx等,所以不需要放到服务器),但是需要定时器,在文件服务器去删除视频,目前我们使用是这种方式。
问题2: sd卡中保存的视频的封装格式是MPEG-PS,普通播放器无法播放,需要转码
解决问题1的时候发现一个问题,将开发板上的文件流,上传到服务器,发现服务器的视频无法播放,经MediaInfo 查看,发现,视频的封装格式为MPEG-PS,这种视频,普通的播放器无法播放的,更别说浏览器自带的了,可以通过万能播放器软件等播放,但是,我们最终是要把视频展示在h5当中,所以,需要进行转码,转成浏览器可以播放的视频格式,查看一些博客和资料,最后发现,可以通过ffmpeg 这个软件,进行编解码,具体资料以及使用方式,可以去雷神的博客学习https://blog.csdn.net/leixiaohua1020/article/details/15811977,注意不同的版本所支持的编解码器不同,根据业务需要使用的编解码器,去下载指定的版本,linux部署的时候踩了不少坑,这里给的下载地址都是可以放心使用的,作者都亲测过.
这里具体说明使用方式:
windows安装:
进入官网,选择需要下载的文件:
官方网址
下载以后,解压到所放置的文件夹:
配置环境变量的步骤如下:
1.打开我的电脑
2.右键鼠标,点击属性
3.选择高级系统设置,然后点击下方的环境变量
4.在系统变量中,找到变量Path,点击值进行编辑,新增一条记录
5.C:\ffmpeg\bin 你自己的安装目录,注意要到bin
6.使用cmd命令,查看ffmpeg版本,如果正常显示
centos7安装教程:
(1).https://blog.csdn.net/u013314786/article/details/89682800
(2).https://linuxize.com/post/how-to-install-ffmpeg-on-centos-7/
linux中这两种方式不需要配置环境变量,如果想要在任意路径使用命令,就需要配置环境变量了,我这里使用的是方式(1)然后每次使用命令都需要到ffmpeg的安装目录下
mac安装
1.官网 https://evermeet.cx/ffmpeg/
mac可以通过brew直接安装的,但是作者这里一直失败,所以用了官网安装
2.选择进行下载
3.下载完成后进行解压,然后放到你自己的目录下,我这里直接放到桌面上的ffmpeg文件夹下了, 我本地安装目录就是:/Users/moch/Desktop/ffmpeg
4.配置环境变量,其实不配也可以,但是你只能在/Users/moch/Desktop/ffmpeg目录下使用ffmpeg命令,我这里配置了全局环境变量,具体如下
5.终端
1. cd ~
2. 使用ls -a可以看到.bash_profile文件
3. vi .bash_profile
//后面的值是你自己的安装路径,切记切记,如果你的path有多个,需要使用:分割
5. 添加 export PATH="/Users/moch/Desktop/ffmpeg"
// 让配置生效
6. source .bash_profile
通过在命令行输入ffmpeg,如出现下图中显示的信息,表示安装成功,图中有版本号,以及当前版本中的编解码器,这里安装结束后,我们测试下,看看是否可以转码为我们想要的格式。
在windows命令行输入
ffmpeg -i c:/video1.MP4 -vcodec libx264 -c:a aac c:/video.flv
其中 -i 后面是源数据 最后面的c:/video.flv是输出路径
至于libx264,aac一个是视频编码,一个是音频编码,因为我需要转成的视频格式为flv,flv的视频编码和音频编码,是avc和aac,至于参数的意思,这里就不详细讲解了,有兴趣的朋友可以去上面发的雷神的博客,或者网上自己学习
最终,生成的flv视频,通过MediaInfo查看
然后通过播放器,可以播放,说明视频转码成功,但是这里只是通过ffmpeg的软件进行操作的,实际操作中,不可能让用户这样操作,所以需要通过代码,调用ffmpeg的接口,进行转码,代码如下(前提是当前电脑的操作系统中,以及安装好了ffmpeg,并且可以正常使用)
配置类
package com.mochitec.hikbox.util;
import lombok.Data;
@Data
public class ConvertProperties {
//linux下,路径肯定不是这样,是/root/xx这样子
private String inputPath = "C:\\Users\\mochu\\Desktop\\video.MP4";
private String outputPath = "C:\\Users\\mochu\\Desktop\\video4.flv";
private String ffmpegPath = "C:\\wym\\ffmpeg\\bin\\"; //linux中,路径为 /root/moch/ffmpeg-4.4-amd64-static/ 你自己在linux服务器上安装的路径
private String convertFlag = "_wait";
}
package com.mochitec.hikbox.util;
import java.io.InputStream;
public class Pr