新写了个直播录制工具,可录制抖音快手斗鱼直播
最近在折腾直播生态,发现很多主播的直播内容值得二次创作(比如剪辑高光时刻、做数据备份),但市面上的录制工具要么收费,要么只支持单一平台。于是我用 Python 手搓了一个跨平台直播录制工具,支持抖音、快手、斗鱼三大主流平台,今天把核心实现思路和代码拆解分享出来。## 为什么自己写?- 现有开源工具(如 streamlink)对国内平台支持差,经常解析失败- 部分平台有风控,直接拉流地址会过期,需要动态获取- 想加入自动重连、定时录制、通知推送等定制功能## 核心技术点1. 流地址解析 :每个平台的直播流地址不是固定的,需要先通过 API 或网页接口拿到 m3u8 或 flv 地址2. 分段下载 :直播流是持续输出的,需要用支持断点续传的方式写入本地3. 异常处理 :网络抖动、主播下播、平台封 IP 等场景必须自动恢复## 代码示例(一):抖音直播流解析抖音的直播流地址藏在 live_room_info 接口里,需要携带 room_id 和 user_agent。以下代码实现了从直播间分享链接提取 room_id,再请求流地址:pythonimport requestsimport reimport jsondef get_douyin_live_url(share_url): """ 从抖音分享链接解析直播流地址 :param share_url: 主播分享的短链接,如 https://v.douyin.com/xxxx/ :return: 直播流 m3u8 地址,或 None """ # 1. 跟随重定向拿到完整链接,提取 room_id resp = requests.get(share_url, allow_redirects=True, timeout=10) final_url = resp.url room_id_match = re.search(r'/(\d+)\?', final_url) if not room_id_match: # 部分链接格式是 /?room_id=xxx room_id_match = re.search(r'room_id=(\d+)', final_url) if not room_id_match: print("无法提取 room_id") return None room_id = room_id_match.group(1) # 2. 请求 live_room_info 接口 api_url = f"https://live.douyin.com/webcast/room/web/enter/?room_id={room_id}" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", "Referer": f"https://live.douyin.com/{room_id}" } data = requests.get(api_url, headers=headers).json() # 3. 解析流地址(注意数据结构可能变化,需容错) try: stream_url = data['data']['room']['stream_url']['hls_pull_url'] return stream_url except KeyError: # 某些直播间可能返回 flv 地址 stream_url = data['data']['room']['stream_url']['flv_pull_url'] return stream_urlif __name__ == "__main__": url = "https://v.douyin.com/test123/" m3u8 = get_douyin_live_url(url) print("解析到直播流:", m3u8)## 代码示例(二):通用录制器(支持快手/斗鱼)快手和斗鱼的解析逻辑类似,只是接口不同。录制部分我封装成一个通用类,支持 m3u8 和 flv 两种协议。这里展示核心录制循环:pythonimport requestsimport timeimport osclass LiveRecorder: def __init__(self, stream_url, output_path, segment_duration=10): """ :param stream_url: 直播流地址(m3u8 或 flv) :param output_path: 输出文件路径(如 ./recording/2024-01-01_20-00.mp4) :param segment_duration: 重连检查间隔(秒) """ self.stream_url = stream_url self.output_path = output_path self.segment_duration = segment_duration self.running = False def start(self): """开始录制,自动处理断流重连""" self.running = True # 确保目录存在 os.makedirs(os.path.dirname(self.output_path), exist_ok=True) # 用流式请求持续写入 with requests.get(self.stream_url, stream=True, timeout=30) as r: if r.status_code != 200: print("请求流地址失败,HTTP状态码:", r.status_code) return # 根据 Content-Type 或 URL 后缀判断是 flv 还是 m3u8 if self.stream_url.endswith('.m3u8'): # m3u8 需要逐段下载 ts 文件,这里简化为直接保存 # 实际项目中需解析 m3u8 列表并循环下载 with open(self.output_path, 'wb') as f: for chunk in r.iter_content(chunk_size=8192): if not self.running: break f.write(chunk) else: # flv 直接写入 with open(self.output_path, 'wb') as f: for chunk in r.iter_content(chunk_size=8192): if not self.running: break f.write(chunk) print("录制结束,文件保存在:", self.output_path) def stop(self): """手动停止录制""" self.running = False# 示例用法(配合上面的抖音解析)if __name__ == "__main__": # 假设已经拿到流地址 stream_url = "https://xxx.douyin.com/stream.m3u8" recorder = LiveRecorder(stream_url, "./recordings/douyin_20240101.mp4") try: recorder.start() # 这会阻塞,直到主播下播或手动 stop except KeyboardInterrupt: recorder.stop() print("用户中断录制")## 实战中的坑与优化1. m3u8 分段下载 :上面代码对 m3u8 做了简化处理,实际中需要解析 .m3u8 文件里的 .ts 片段列表,逐个下载并合并。推荐用 ffmpeg 直接拉流,更加稳定: bash ffmpeg -i "stream_url" -c copy output.mp4 但在 Python 里可以用 subprocess 调用 ffmpeg,并监控进程状态。2. 快手平台 :快手的流地址在 https://live.kuaishou.com/live_api/... 接口中,需要带 cookies 和 userId,建议用 selenium 模拟登录获取 token,否则容易 403。3. 斗鱼 :斗鱼的流地址有防盗链,需要 Referer 必须为 https://www.douyu.com,同时需要解析 https://www.douyu.com/betard/{room_id} 接口拿到 rtmp_live 地址。4. 自动重连 :直播经常断线,建议用 while 循环包裹录制逻辑,捕获 requests.exceptions.ConnectionError,等待 5 秒后重新拉流。## 完整工具架构我最终把工具做成了命令行模式:bashpython live_recorder.py --platform douyin --url "https://v.douyin.com/xxx" --output ./videos核心模块包括:- parser/:各平台流地址解析器- recorder/:录制核心(支持 ffmpeg 后端)- notifier/:录制结束后推送企业微信/钉钉通知- scheduler/:定时录制功能(比如每天固定时间录制某主播)## 总结通过这个项目,我深入理解了直播流协议(HLS/FLV)的差异,也踩了不少反爬的坑。最终工具支持三大平台,且代码模块化,方便扩展其他平台。如果你也常需要录制直播,不妨试试自己动手------不仅能定制功能,还能学习到流媒体处理的实战经验。完整源码已开源在 GitHub(链接略),欢迎 star 和提 PR。希望这篇文章对你有所帮助,如果有问题,欢迎在评论区交流!