[QUESTION] fetch_user_live_videos和fetch_user_live_videos_by_room_id 下载直播流
- [ ] ~~在提问时请注意不要包含个人敏感信息~~
- [ ] 我明白我的提问可能不会得到明确回复或解决。
问题描述
使用示范代码配合webcast_id下载直播流是正常的,改成room_id就失败,传回的值都为空,不知道哪里没改好。 room_id是有效的,可以拿来下载wss弹幕。 因为webcast_id没办法抓到单人语音直播间,所以只能选择用room_id。
= RESTART: C:\Users\CC\Downloads\f2弹幕下载\douyin_downloader.py
INFO 处理房间号: 7538611852025023284 的直播数据
INFO 直播ID:未知,用户:未知,直播间:无标题,状态:未知状态,观看人数:0
ERROR 直播间ID:7538611852025023284 下载失败:'NoneType' object has no
attribute 'items'
其他细节
使用的代码如下:
import asyncio
import traceback
from f2.apps.douyin.handler import DouyinHandler
from f2.apps.douyin.db import AsyncUserDB
from f2.apps.douyin.dl import DouyinDownloader
from f2.utils.conf_manager import ConfigManager
from f2.log.logger import logger # 确保导入logger
from f2.apps.douyin.utils import TokenManager
from f2.cli.cli_console import RichConsoleManager
全局配置参数,保护敏感信息
kwargs = { "headers": { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0", "Referer": "https://www.douyin.com/", }, "proxies": {"http://": None, "https://": None}, # 指定模式 "mode": "live", } | ConfigManager("conf/app.yaml").get_config("douyin")
实例化下载器和处理器
dydownloader = DouyinDownloader(kwargs) dyhandler = DouyinHandler(kwargs)
async def download_live_stream( room_id: str, # 接收的是字符串类型的 room_id ): """ 下载单个直播间的直播流,直到流断开
Args:
room_id (str): 直播间ID (Room ID)
"""
try:
room_id_str = str(room_id)
logger.debug(f"尝试获取直播间 {room_id_str} 信息...")
# 获取直播间信息
live = await dyhandler.fetch_user_live_videos_by_room_id(room_id=room_id_str)
if live is None:
logger.error(f"无法获取直播间 {room_id_str} 信息,API 返回 None")
return
logger.debug(f"直播间信息: {live._to_dict()}") # 查看返回的数据结构
if live.live_status != 2:
logger.info(f"直播间 {room_id_str} 当前未开播 (状态: {live.live_status})")
return
async with AsyncUserDB("douyin_users.db") as audb:
user_path = await dyhandler.get_or_add_user_data(
kwargs, live.sec_user_id, audb
)
logger.debug(
f"[bold green]开始下载直播间ID:{room_id_str} 的直播流...[/bold green]"
)
await dydownloader.create_stream_tasks(kwargs, live._to_dict(), user_path)
logger.info(
f"[bold green]直播间ID:{room_id_str} 直播流已结束,下载完成。[/bold green]"
)
except Exception as e:
logger.error(f"[bold red]直播间ID:{room_id_str} 下载失败:{e}[/bold red]")
主函数,用于下载单个直播间的直播流
async def main(room_id: str): await download_live_stream(room_id)
if name == "main": try: room_id = "7538611852025023284" # 你可以在这里传入任何需要下载的房间ID asyncio.run(main(room_id)) except KeyboardInterrupt: logger.info("[bold yellow]程序已手动停止[/bold yellow]") except Exception as e: logger.error(f"[bold red]程序运行时出现异常: {e}[/bold red]") logger.error(traceback.format_exc())
Similarity Issues
- 70% #357
- 70% #356
- 70% #355
- 70% #348
- 70% #347
- 70% #305
Hi @CCMonkeyss! I'm Dosu and I’m helping the f2 team.
webcast_id 和 room_id 是抖音直播的两个不同标识符,分别对应不同的 API 接口,不能混用。用 room_id 下载直播流时,fetch_user_live_videos_by_room_id 方法会调用专门的接口获取直播数据,但如果 API 返回的数据结构不完整(比如缺少 sec_user_id、live_status 等关键字段),或者 room_id 对应的直播间不是“正在直播”状态,就会返回 None,导致你看到的 'NoneType' object has no attribute 'items' 错误。即使 room_id 能用于弹幕(wss),也不一定能用于下载直播流,因为弹幕和视频流的接口不同,返回的数据结构也不同。
建议排查:1)room_id 是否对应正在直播的房间(live_status 必须为 2);2)API 请求是否带上了完整的 cookie(部分直播间需要登录态);3)检查 API 返回的数据结构是否完整,可以在 debug 日志里打印 live._to_raw() 或 live._to_dict() 看实际内容;4)确认 room_id 来源是否为 APP 分享的直播链接(不是短链 r_id)参考。
详细接口和参数说明见 官方文档。
To reply, just mention @dosu.
How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other