环境
- ubuntu 18.04 64bit
- ZLMediaKit 20210924
- ffmpeg 3.4.8
前言
简单地说,webhook
是一个 HTTP
回调,在大多数情况下,用于系统之间的通信。当系统中的某个事件发生时,会以 HTTP POST
的方式告诉其它系统,以此来达到实时通知的效果。
webhook
通常的数据传输格式是 json
或者 xml
,使用的 http
请求方法是 POST
ZLMediaKit中的webhook
默认情况下,zlmediakit
并没有开启 web hook
,我们编辑一下配置文件 config.ini
,定位到 hook
配置的部分
[hook]
#在推流时,如果url参数匹对admin_params,那么可以不经过hook鉴权直接推流成功,播放时亦然
#该配置项的目的是为了开发者自己调试测试,该参数暴露后会有泄露隐私的安全隐患
admin_params=secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc
#是否启用hook事件,启用后,推拉流都将进行鉴权
enable=1
#播放器或推流器使用流量事件,置空则关闭
on_flow_report=https://127.0.0.1/index/hook/on_flow_report
#访问http文件鉴权事件,置空则关闭鉴权
# on_http_access=https://127.0.0.1/index/hook/on_http_access
on_http_access=http://192.168.1.115:5000/index/hook/on_http_access
#播放鉴权事件,置空则关闭鉴权
# on_play=https://127.0.0.1/index/hook/on_play
on_play=http://192.168.1.115:5000/index/hook/on_play
#推流鉴权事件,置空则关闭鉴权
on_publish=https://127.0.0.1/index/hook/on_publish
#录制mp4切片完成事件
on_record_mp4=https://127.0.0.1/index/hook/on_record_mp4
# 录制 hls ts 切片完成事件
on_record_ts=https://127.0.0.1/index/hook/on_record_ts
#rtsp播放鉴权事件,此事件中比对rtsp的用户名密码
on_rtsp_auth=https://127.0.0.1/index/hook/on_rtsp_auth
#rtsp播放是否开启专属鉴权事件,置空则关闭rtsp鉴权。rtsp播放鉴权还支持url方式鉴权
#建议开发者统一采用url参数方式鉴权,rtsp用户名密码鉴权一般在设备上用的比较多
#开启rtsp专属鉴权后,将不再触发on_play鉴权事件
on_rtsp_realm=https://127.0.0.1/index/hook/on_rtsp_realm
#远程telnet调试鉴权事件
on_shell_login=https://127.0.0.1/index/hook/on_shell_login
#直播流注册或注销事件
on_stream_changed=https://127.0.0.1/index/hook/on_stream_changed
#无人观看流事件,通过该事件,可以选择是否关闭无人观看的流。配合general.streamNoneReaderDelayMS选项一起使用
on_stream_none_reader=https://127.0.0.1/index/hook/on_stream_none_reader
#播放时,未找到流事件,通过配合hook.on_stream_none_reader事件可以完成按需拉流
on_stream_not_found=https://127.0.0.1/index/hook/on_stream_not_found
#服务器启动报告,可以用于服务器的崩溃重启事件监听
on_server_started=https://127.0.0.1/index/hook/on_server_started
#server保活上报
on_server_keepalive=https://127.0.0.1/index/hook/on_server_keepalive
#hook api最大等待回复时间,单位秒
timeoutSec=10
#keepalive hook触发间隔,单位秒,float类型
alive_interval=10.0
这里将 enable
设置成了1,也就是启用该功能,然后将 on_http_access
和 on_play
对应的 url
进行了修改
on_http_access=http://192.168.1.115:5000/index/hook/on_http_access
on_play=http://192.168.1.115:5000/index/hook/on_play
其中,192.168.1.115
是提供服务的服务器 ip
地址,我们会在这个服务器上开启 web
服务,响应 ZLMediaKit
服务 POST
上来的请求
其它事件也是类似的,完成后,启动服务
sudo ./MediaServer -d
接下来,我们使用 flask
来编写一个 web
服务,用来响应 on_http_access
和 on_play
的请求。使用其它语言或其它框架也都是可以的
from flask import Flask
app = Flask(__name__)
@app.route('/index/hook/on_http_access', methods=['GET', 'POST'])
def on_http_access():
print('on_http_access!')
return "on_http_access!"
@app.route('/index/hook/on_play', methods=['GET', 'POST'])
def on_play():
print('on_play!')
return "on_play!"
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
作为示例,我们的服务非常简单,仅有一个打印语句,返回的也是一个字符串,同样的,也启动 flask
服务
python main.py
接下来就可以测试了,打开浏览器,输入 http://192.168.1.140,访问 zlmediakit
的 web
服务
这时候注意看 flask
服务的输出信息,打印了 on_http_access!
的信息,但是浏览器页面上报错了,显示 [parse json failed]:reader error
,这是由于我们的 flask
中的响应函数返回的是字符串,而不是 json
格式的数据,这个后面再来改
同样的,我们来测试下播放。打开一个终端,将本地测试视频推送到 ZLMediaKit
ffmpeg -re -i test.mp4 -vcodec h264 -acodec aac -f flv rtmp://127.0.0.1/live/test
然后在另一个终端中进行播放测试
ffplay.exe rtmp://192.168.1.140/live/test
可以看到,flask
的后台同样输出了对应的消息 on_play!
,而由于 json
数据返回的原因,ffplay
无法完成视频播放
好了,webhook
的基本功能看上去是正常的,那最后,我们来完善一下 flask
中的代码,让客户端的 http
访问和播放器播放能够正常工作
具体的 json
数据格式参考 https://github.com/zlmediakit/ZLMediaKit/wiki/MediaServer%E6%94%AF%E6%8C%81%E7%9A%84HTTP-HOOK-API
来到 flask
中的 on_http_access
和 on_play
方法,重写 return
部分的语句
@app.route('/index/hook/on_http_access', methods=['GET', 'POST'])
def on_http_access():
print('on_http_access!')
return jsonify(
{
"code": 0,
"err": "",
"path": "",
"second": 600
}
)
@app.route('/index/hook/on_play', methods=['GET', 'POST'])
def on_play():
print('on_play!')
return jsonify(
{
"code": 0,
"msg": "success"
}
)
完成后,重启服务,浏览器中访问 http://192.168.1.140,可以看到,访问正常了
同理,播放器中的播放也正常了