ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

instagram-private-api 中 ReelsTrayFeedResponseBroadcastsItem 接口详解:解析 Reels 托盘里的直播(Broadcasts)数据

instagram-private-api 中 ReelsTrayFeedResponseBroadcastsItem 接口详解:解析 Reels 托盘里的直播(Broadcasts)数据
  • 后端

【免费下载链接】instagram-private-api

NodeJS Instagram private API SDK. Written in TypeScript.

项目地址:https://gitcode.com/gh_mirrors/in/instagram-private-api
点击查看免费下载

本篇技术指南围绕 instagram-private-api 中 ReelsTrayFeedResponseBroadcastsItem 接口展开:它定义了/api/v1/feed/reels_tray/接口响应中broadcasts数组项的完整结构,也就是 Instagram 快拍托盘里正在直播的用户的元数据。读完后你将掌握如何获取该响应、逐字段解析直播状态/播放地址/榜单位置等信息,并理解它与 Live 模块响应结构的关系。

一、接口在项目中的位置:Reels Tray 响应的顶层结构

ReelsTrayFeedResponseBroadcastsItem定义于 src/responses/reels-tray.feed.response.ts,它是 ReelsTrayFeed 对应响应根对象的一部分。根对象结构如下(src/responses/reels-tray.feed.response.ts#L1-L10):

export interface ReelsTrayFeedResponseRootObject { tray: ReelsTrayFeedResponseTrayItem[]; // 好友快拍(Stories)列表 story_ranking_token: string; broadcasts: ReelsTrayFeedResponseBroadcastsItem[]; // 正在直播的用户列表,本文主角 sticker_version: number; face_filter_nux_version: number; stories_viewer_gestures_nux_eligible: boolean; has_new_nux_story: boolean; status: string; }

也就是说,同一次 Reels Tray 请求会同时返回两类内容:tray(快拍)与broadcasts(直播)。本文聚焦的ReelsTrayFeedResponseBroadcastsItem数组中每一项,对应一个正在直播的账号。

需要特别注意的是 src/feeds/reels-tray.feed.ts 中items()方法的实现:

/** * Returns only the stories (without the broadcasts) */ async items(): Promise<ReelsTrayFeedResponseTrayItem[]> { const response = await this.request(); return response.tray; }

从源码看,items()被刻意设计为只返回快拍、丢弃直播数据。如果你需要读取broadcasts,应当调用request()拿到完整的ReelsTrayFeedResponseRootObject,再访问body.broadcasts字段。

二、完整字段参考表

以下表格完整继承了 接口文档 中列出的全部 21 个属性,并结合 源码定义 按功能分组说明。

2.1 身份与状态字段

字段类型源码行号说明
idstringL230直播(broadcast)的唯一标识,可作为ig.live相关方法的broadcastId入参
media_idstringL248直播对应的媒体 ID
broadcast_statusstringL235直播状态字符串,可用于判断直播是否仍在进行
published_timenumberL246直播开始时间(Unix 时间戳)

2.2 播放地址字段

字段类型源码行号说明
rtmp_playback_urlstringL231RTMP 播放地址(推流/回放链路常用协议)
dash_playback_urlstringL232DASH 播放地址
dash_abr_playback_urlnullL233DASH ABR 播放地址;类型被固定声明为null,表明该仓库对接的响应版本中此字段实测恒为空
dash_live_predictive_playback_urlstringL234直播预测式播放地址,用于播放器预拉流优化
cover_frame_urlstringL241直播封面帧图片地址,可用于在列表中渲染直播缩略图

2.3 观看量、排序与可见性字段

字段类型源码行号说明
viewer_countnumberL236当前观看人数
internal_onlybooleanL237是否为内部直播(仅内部可见)
mutedbooleanL238该直播是否被当前用户静音
ranked_positionnumberL239该直播在托盘中的排序位置
seen_ranked_positionnumberL240用户已看到的位置进度,客户端据此区分"未看"与"已看"项
hide_from_feed_unitbooleanL247是否应从信息流单元中隐藏该直播

ranked_position与seen_ranked_position的字段命名和用法与同文件中ReelsTrayFeedResponseTrayItem快拍项(L20-L21)保持一致,可以看出直播项与快拍项共用同一套托盘排序/已读机制。

2.4 内容与播放特性字段

字段类型源码行号说明
cobroadcastersany[]L242联合主播列表;源码中类型声明为any[],属于尚未精细建模的透传字段,解析时应做防御性处理
is_player_live_trace_enablednumberL243播放器直播追踪开关(数字而非布尔,为服务端原始表示)
is_gaming_contentbooleanL244是否为游戏直播内容

2.5 主播信息与埋点字段

字段类型源码行号说明
broadcast_ownerReelsTrayFeedResponseBroadcast_ownerL245主播用户对象,结构见下节
broadcast_messagestringL249直播标题/广播消息文案
organic_tracking_tokenstringL250自然流量追踪 token,用于埋点归因,业务侧一般无需处理

2.6 嵌套对象:broadcast_owner

broadcast_owner的完整结构定义在 src/responses/reels-tray.feed.response.ts#L252-L262:

export interface ReelsTrayFeedResponseBroadcast_owner { pk: number; username: string; full_name: string; is_private: boolean; profile_pic_url: string; profile_pic_id: string; friendship_status: ReelsTrayFeedResponseFriendship_status; is_verified: boolean; live_subscription_status: string; }

其中friendship_status复用同文件中的 ReelsTrayFeedResponseFriendship_status(含following、followed_by、muting、is_private、is_bestie等字段),可用于判断当前登录账号与主播之间的关注/互关/限制关系。live_subscription_status是该主播订阅状态的字符串表示。

三、如何在代码中获取 broadcasts 数据

3.1 通过 Feed 工厂创建 ReelsTrayFeed

Feed 工厂方法位于 src/core/feed.factory.ts#L161-L163:

public reelsTray(reason: 'pull_to_refresh' | 'cold_start' = 'cold_start'): ReelsTrayFeed { return plainToClassFromExist(new ReelsTrayFeed(this.client), { reason }); }

reason只有两个取值:cold_start(冷启动,默认)与pull_to_refresh(下拉刷新),会以表单项形式随请求提交。

3.2 底层请求细节

ReelsTrayFeed.request()的实现(src/feeds/reels-tray.feed.ts#L17-L30)以 POST 方式请求/api/v1/feed/reels_tray/,表单包含 4 个参数:

const { body } = await this.client.request.send<ReelsTrayFeedResponseRootObject>({ url: '/api/v1/feed/reels_tray/', method: 'POST', form: { supported_capabilities_new: this.client.state.supportedCapabilities, reason: this.reason, _csrftoken: this.client.state.cookieCsrfToken, _uuid: this.client.state.uuid, }, }); this.state = body; return body;

可见该接口依赖登录态(_csrftoken取自 cookie),且设备指纹由supported_capabilities_new携带——使用前必须先完成ig.state.generateDevice(...)与ig.account.login(...)。

3.3 完整调用示例

以下示例的登录部分与仓库内 examples/user-stories-watching.example.ts 保持一致:

import 'dotenv/config'; import { IgApiClient } from 'instagram-private-api'; (async () => { const ig = new IgApiClient(); ig.state.generateDevice(process.env.IG_USERNAME); ig.state.proxyUrl = process.env.IG_PROXY; // 可选 await ig.account.login(process.env.IG_USERNAME, process.env.IG_PASSWORD); // 1. 创建 Reels Tray Feed(reason 默认 cold_start) const feed = ig.feed.reelsTray('cold_start'); // 2. items() 只返回 tray(快拍),要拿直播必须走 request() const response = await feed.request(); // 3. 遍历正在直播的账号 for (const live of response.broadcasts) { console.log(live.broadcast_owner.username, live.broadcast_message); console.log('status:', live.broadcast_status, 'viewers:', live.viewer_count); console.log('dash url:', live.dash_playback_url); console.log('cover:', live.cover_frame_url); } })();

3.4 Feed 基类的通用机制

ReelsTrayFeed继承自 src/core/feed.ts 中的Feed抽象类,从源码结构看有两点值得了解:

  • 基类提供items$/observable()(src/core/feed.ts#L18-L61):基于 RxJS +@lifeomic/attempt实现带指数退避的重试轮询,遇 400/429/500/502 会等待后自动重试。注意对ReelsTrayFeed而言,items()已重写为"只取 tray",因此 Observable 流中不会包含直播项;
  • request()的返回体会写入 feed 的state,随后toPlain()/serialize()可将其持久化(moreAvailable等字段经@Expose()暴露)。

四、与 Live 模块的对照:同一直播实体、两个入口

阅读 src/responses/live.info.response.ts#L1-L20 中的LiveInfoResponseRootObject会发现,它拥有几乎完全一致的字段集合(id、rtmp_playback_url、dash_playback_url、dash_abr_playback_url: null、dash_live_predictive_playback_url、broadcast_status、viewer_count、internal_only、cobroadcasters、is_player_live_trace_enabled、is_gaming_content、broadcast_owner、published_time、hide_from_feed_unit、media_id、broadcast_message、organic_tracking_token),并额外多出status字段;而ReelsTrayFeedResponseBroadcastsItem额外带有muted、ranked_position、seen_ranked_position、cover_frame_url这类"托盘展示"语义的字段。

可以推断:Instagram 服务端对同一个直播实体在"直播详情接口"和"快拍托盘接口"中返回了两种形态——前者面向播放,后者面向列表展示。仓库中的 LiveRepository.info() 通过GET /api/v1/live/{broadcastId}/info/获取前者,因此一个典型的工作流是:

  1. 通过ig.feed.reelsTray()+request()发现broadcasts中的直播(拿到id与封面、观看数);
  2. 用ig.live.info(broadcast.id)或ig.live.heartbeatAndGetViewerCount(broadcast.id)(src/repositories/live.repository.ts#L55-L66)继续查询/维持观看会话。

五、使用注意与文档溯源

  • 字段是服务端响应的静态快照:该接口按抓包响应逐字段建模,dash_abr_playback_url固定为null、cobroadcasters为any[]都说明这是"以实际响应为准"的类型策略。若 Instagram 调整响应结构,接口定义需随之更新,解析代码应保持可选性。
  • 文档与源码的对应关系:本文所引用的接口文档 docs/interfaces/responses/ReelsTrayFeedResponseBroadcastsItem.md 由仓库的 TypeDoc 流程生成(见 tsconfig.docs.json、typedoc.json),每个属性都标注了Defined in指向 src/responses/reels-tray.feed.response.ts 的具体行号,与当前仓库源码一致;接口还通过 src/responses/index.ts 统一导出,供ReelsTrayFeed等模块导入。
  • 适用前提:该 Feed 需要有效的登录会话与设备指纹(_csrftoken、_uuid、supported_capabilities_new),未登录场景无法获取托盘直播数据;reason参数的取值会影响服务端返回策略,请按真实客户端语义选择。

小结

ReelsTrayFeedResponseBroadcastsItem是 instagram-private-api 中把 Instagram "好友托盘直播"数据结构化访问的关键接口:21 个字段覆盖了直播身份(id/media_id)、播放链路(RTMP/DASH 地址)、展示语义(排序位、静音、封面)、主播信息(broadcast_owner)与埋点(organic_tracking_token)。通过ig.feed.reelsTray().request()拿到完整响应后,即可在不依赖 Live 模块的情况下枚举当前可见直播,并借助broadcast_owner.pk、id等字段与 src/repositories/live.repository.ts 中的直播方法衔接,实现"发现直播 → 查看详情 → 维持观看"的完整链路。

  • 后端

【免费下载链接】instagram-private-api

NodeJS Instagram private API SDK. Written in TypeScript.

项目地址:https://gitcode.com/gh_mirrors/in/instagram-private-api
点击查看免费下载
上一篇:Android视频压缩终极方案:基于MediaCodec硬件加速的高性能实现
下一篇:解锁多模态创作能力:ComfyUI音频处理框架的创新实践

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进