前言
使用该组合的目的是在尽量少的外网暴露端口下,更轻量且便捷的进行通话操作,同时边缘物联网盒子的资源占用也更小。
但由于通话过程中盒子端会有一定的延迟现象(网络高峰期出现),且通信的信令协调需要手动实现,在简单情景下使用比较适合
主交互过程
![image]()
服务端
部署后可在页面直接通过 webrtc 来访问
这里记录的是如何进行编译安装,使用的环境是 amd64 下的 Deepin23.1
折叠代码块BASH
复制代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
sudo apt-get update
sudo apt-get install -y build-essential cmake
sudo apt-get install -y ffmpeg libssl-dev libsdl-dev libavcodec-dev libavutil-dev
git clone --depth 1 https://gitee.com/xia-chu/ZLMediaKit cd ZLMediaKit
git submodule update --init
mkdir temp cd temp
mkdir software
git clone https://github.com/openssl/openssl.git cd openssl
./config --prefix=/home/easul/software/ZLMediaKit/temp/software/openssl make -j4 make install cd ../software/openssl cp -r lib64 lib
cd ../../ git clone https://github.com/cisco/libsrtp.git
cd libsrtp ./configure --enable-openssl --with-openssl-dir=/home/easul/software/ZLMediaKit/temp/software/openssl make -j4
sudo make install
cd ../../ mkdir build cd build
cmake .. -DENABLE_WEBRTC=true -DOPENSSL_ROOT_DIR=/home/easul/software/ZLMediaKit/temp/software/openssl -DOPENSSL_LIBRARIES=/home/easul/software/ZLMediaKit/temp/software/openssl/lib -DCMAKE_VERBOSE_MAKEFILE=ON
cmake --build . --target MediaServer -- -j1 VERBOSE=1
cd ../release/linux/Debug
./MediaServer
|
编译后的一些可能需要的操作
折叠代码块BASH
复制代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
rm -rf /usr/local/include/srtp3 rm -f /usr/local/lib/libsrtp3.* rm -f /usr/local/lib/pkgconfig/libsrtp3.pc
|
参考文档如下
客户端
这里都是用 screen 进行会话管理,且以下内容中使用的命令,如果报错,则需要再安装一下
盒子推送和接收音频流
由于原本的设想是只让服务端暴露一个端口进行数据传输,故而这里都是在盒子使用frp进行数据通道建立,然后再进行数据的传输与拉取。
这里将盒子本地端口 12347 映射到了服务器的 26002 端口,将盒子本地端口 12345 映射到了服务器的 26000,最终盒子和服务端都相当于使用了本地端口来进行数据通信。
折叠代码块BASH
复制代码
1 2 3 4 5 6
| screen -dmS frp /root/workspace/temp/frp/frp_0.65.0_linux_arm_hf/frpc -c /root/workspace/temp/frp/frp_0.65.0_linux_arm_hf/frpc.toml > /root/workspace/temp/frp/frp_0.65.0_linux_arm_hf/frpc.log
screen -dmS audio_send bash -c "arecord -D plughw:1,0 -f S16_LE -r 8000 -c 1 | /root/workspace/ffmpeg/ffmpeg -f s16le -ar 8000 -ac 1 -i - -c:a libopus -af "aresample=async=1:first_pts=0" -f mpegts tcp://127.0.0.1:12347?listen=1"
screen -dmS audio_recv bash -c "socat TCP-LISTEN:12345,reuseaddr,fork - | aplay -D plughw:1,0 -f S16_LE -r 8000 -c 1 -q -t raw"
|
用户的电脑
折叠代码块BASH
复制代码
1 2
| screen -dmS audio_send bash -c "arecord -D plughw:0,0 -f S16_LE -r 8000 -c 1 | ffmpeg -f s16le -ar 8000 -ac 1 -i - -af "highpass=f=80,afftdn" -c:a pcm_mulaw -f rtsp rtsp://127.0.0.1/live/box_audio"
|
服务器
服务器端部署了frp,因为盒子端的相关数据只需要在内网环境下进行访问,故而这里frp端口不需要暴露到外网,从而减少了外网端口的使用。
折叠代码块BASH
复制代码
1 2 3 4 5 6
|
screen -dmS audio_recv ffmpeg -thread_queue_size 1024 -i tcp://0.0.0.0:26002 -b:v 600k -maxrate 600k -bufsize 300k -af "highpass=f=80,afftdn" -c:a libopus -fflags nobuffer -flags low_delay -max_delay 0 -f rtsp rtsp://127.0.0.1/live/test
screen -dmS audio_send ffmpeg -fflags nobuffer -flags low_delay -nostats -hide_banner -i rtsp://127.0.0.1/live/box_audio -map a -ar 8000 -ac 1 -c:a pcm_s16le -f s16le tcp://127.0.0.1:26000
|
其他
盒子端使用不同协议处理数据流
由于盒子端使用 TCP 和 UDP 协议进行数据推送时效果和能力也不相同,故以下提供了盒子端进行两种协议下推送和接收流的方式。
TCP
折叠代码块BASH
复制代码
1 2 3 4
| screen -dmS audio_recv bash -c "socat -u TCP-LISTEN:12345,reuseaddr,fork - | aplay -D plughw:1,0 -f S16_LE -r 8000 -c 1 -q -t raw"
screen -dmS audio_send ffmpeg -fflags nobuffer -flags low_delay -nostats -hide_banner -i rtsp://127.0.0.1/live/box_audio -map a -ar 8000 -ac 1 -c:a pcm_s16le -max_muxing_queue_size 1024 -buffer_size 1024 -f s16le tcp://127.0.0.1:26000
|
UDP
折叠代码块BASH
复制代码
1 2 3 4
| screen -dmS audio_recv bash -c "socat -u UDP-LISTEN:12345,reuseaddr,fork - | aplay -D plughw:1,0 -f S16_LE -r 8000 -c 1 -q -t raw"
screen -dmS audio_send ffmpeg -fflags nobuffer -flags low_delay -nostats -hide_banner -i rtsp://127.0.0.1/live/box_audio -map a -ar 8000 -ac 1 -c:a pcm_s16le -f s16le udp://127.0.0.1:26000?pkt_size=512
|
视音频同时处理
这里记录一下盒子端将摄像头和麦克风的数据一起处理的方式
盒子推服务端
折叠代码块BASH
复制代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| arecord -D plughw:1,0 -f cd | nc -u 192.168.1.12 22555
ffmpeg -rtsp_transport tcp -i "rtsp://camera_user:camera_pass@ip:554/h264/ch1/sub/av_stream" -c:v copy -f mpegts - | nc -u 192.168.1.12 22554
ffmpeg \ -f mpegts -i udp://0.0.0.0:22554?listen=1 \ -f s16le -ar 44100 -ac 2 -i udp://0.0.0.0:22555?listen=1 \ -c:v libx264 -preset veryfast -tune zerolatency \ -x264opts keyint=25:min-keyint=25:scenecut=-1 \ -c:a aac -b:a 64k \ -f rtsp rtsp://192.168.1.88/live/test
ffmpeg \ -f mpegts -i udp://0.0.0.0:22554?listen=1 \ -f s16le -ar 44100 -ac 2 -i udp://0.0.0.0:22555?listen=1 \ -c:v libx264 -preset veryfast -tune zerolatency \ -x264opts keyint=25:min-keyint=25:scenecut=-1 \ -c:a aac -b:a 64k \ -f hls \ -hls_time 2 \ -hls_list_size 5 \ -hls_flags delete_segments \ /home/easul/Desktop/result/box_av.m3u8
|
服务端推盒子端
这里默认网络可以直连
分开推
折叠代码块BASH
复制代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| arecord -D plughw:0,0 -f cd - | \ ffmpeg -f s16le -ar 48000 -ac 2 -i - \ -c:a aac -b:a 64k -f flv rtmp://192.168.1.88/live/box_audio
./ffmpeg -i rtmp://192.168.1.12/live/box_audio \ -f alsa -ac 2 hw:1,0
./ffmpeg -i rtmp://192.168.1.12/live/box_audio \ -vn \ -ar 48000 -ac 2 -c:a pcm_s16le \ -f alsa hw:1,0
|
一起推
折叠代码块BASH
复制代码
1 2 3 4 5 6 7 8 9 10 11 12 13
| ffmpeg -rtsp_transport tcp -i "rtsp://camera_user:camera_pass@IP:554/h264/ch1/sub/av_stream" -vcodec h264 -an -bf 0 -f flv "rtmp://192.168.1.88/live/test"
ffmpeg -rtsp_transport tcp -i "rtsp://camera_user:camera_pass@IP:554/h264/ch1/sub/av_stream" -c:v copy -c:a copy -bf 0 -f flv "rtmp://192.168.1.88/live/test"
arecord -D plughw:0,0 -f cd -r 8000 -c 1 | \ ffmpeg -rtsp_transport tcp -fflags nobuffer -flags low_delay -rtbufsize 64k \ -i "rtsp://camera_user:camera_pass@IP:554/h264/ch1/sub/av_stream" \ -f s16le -ar 8000 -ac 1 -i - \ -c:v libx264 -preset ultrafast -tune zerolatency -crf 23 -bf 0 \ -c:a pcm_mulaw -af aresample=async=1:first_pts=0 \ -map 0:v:0 -map 1:a:0 \ -f rtsp "rtsp://192.168.1.88/live/test"
|
其他服务端组件尝试
在尝试过程中,同样使用过
- srs : 实时流媒体服务器,主要用于协议转换,从而方便前端调用。
- janus-gateway: 用于前端WebRTC使用以及通话中RTP的处理。
- coturn: 用于WebRTC 系统里的网络中继服务器(用于实时通话流量传输)。
由于编译、运行或者与当前场景集成遇到的问题暂时无法快速解决,故未使用这些项目。
v1.5.2