说在前面
- 操作系统:windows10(别问我为啥在windows下)
- 测试浏览器:chrome86.0、edge(旧版不支持)
- go版本:1.14.1
- 相关库:pion/webrtc(应该是3.0.0版本)
- 吐槽:我又来整视频流相关的东西,这一篇是简单修改了它的一个demo
准备工作
- go
自行安装,不再赘述 - ffmpeg
自行安装,不再赘述 - pion-webrtc
# windows set GO111MODULE=on go get github.com/pion/webrtc/v3 # 再找一个存放文件的目录 git clone https://github.com/pion/webrtc.git cd path\webrtc\examples
server
-
启动
go run examples.go --address localhost:8080
这里貌似只是简单的作为一个
webserver
-
测试
浏览器打开127.0.0.1:8080
-
注意
如果你的界面是下面这种
(已修复)请将webrtc\examples\insertable-streams\jsfiddle
目录下的demo.js
的以下代码:const reader = receiverStreams.readableStream.getReader() const writer = receiverStreams.writableStream.getWriter()
改为
const reader = receiverStreams.readable.getReader() const writer = receiverStreams.writable.getWriter()
运行
-
重新打开一个cmd窗口
-
创建
.ivf
文件ffmpeg -i test.mp4 -g 30 output.ivf
将该
.ivf
文件复制到webrtc\examples\insertable-streams
目录下 -
复制
Browser base64 Session Description
创建一个文本文件如file.txt
,并将上述文本复制到文件中,该文件移动到webrtc\examples\insertable-streams
目录下 -
运行
main.go
cd path\webrtc\examples\insertable-streams go run main.go < file.txt
这个时候会生成一个
Golang base64 Session Description
将其复制到
点击Start Session
,可以看到结果
修改
cnt := uint64(0)
for {
cnt++
// 增加8个字节的帧号到frame尾部
b := make([]byte, 8)
binary.BigEndian.PutUint64(b, cnt)
frame, _, ivfErr := ivf.ParseNextFrame()
if ivfErr == io.EOF {
fmt.Printf("All frames parsed and sent")
os.Exit(0)
}
if ivfErr != nil {
panic(ivfErr)
}
// Encrypt video using XOR Cipher
for i := range frame {
frame[i] ^= cipherKey
}
// 到frame尾部
frame = append(frame, b...)
// ...
前端js改动
reader.read().then(function processVideo({ done, value }) {
let decrypted = new DataView(value.data)
if (applyDecryption) {
// 不处理尾部8字节
for (let i = 0; i < decrypted.buffer.byteLength - 8; i++) {
decrypted.setInt8(i, decrypted.getInt8(i) ^ cipherKey)
}
}
// 解析尾部8字节的数据
console.log(toUint32(new Uint8Array(decrypted.buffer.slice(decrypted.buffer.byteLength - 4, decrypted.buffer.byteLength))))
// 去掉尾部8字节
value.data = decrypted.buffer.slice(0, decrypted.buffer.byteLength - 8)
writer.write(value)
return reader.read().then(processVideo)
})