Douyin Live Recorder - Real-Time Chat, Gifts & MP4 Capture avatar

Douyin Live Recorder - Real-Time Chat, Gifts & MP4 Capture

Pricing

from $0.85 / 1,000 recording seconds

Go to Apify Store
Douyin Live Recorder - Real-Time Chat, Gifts & MP4 Capture

Douyin Live Recorder - Real-Time Chat, Gifts & MP4 Capture

Extract real-time chats, gifts, likes, joins, follows, and viewer counts from Douyin (抖音) live broadcasts. Save the stream as MP4 segments. Polymorphic JSON dataset, one row per event. SD to Full HD recording. Free tier included.

Pricing

from $0.85 / 1,000 recording seconds

Rating

0.0

(0)

Developer

Zen Studio

Zen Studio

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

Douyin Live Recorder | Real-time Chat, Gift & Viewer Stream + MP4 Capture (2026)

15+ event types streamed in real time, optional MP4 capture in SD–Full HD — chats, gifts, likes, joins, follows, viewer counts, room rankings, and stream control signals. One row per event. The most complete Douyin (抖音) live recorder on Apify.

Douyin Live Recorder

Zen Studio China Suite   •  Profiles, posts, transcripts, and live broadcasts from 抖音 — plus search from 小红书
 Profile Scraper
46 author fields + post lists
 Video Scraper
Full video metadata by URL
 Transcripts Scraper
Subtitles + ASR + translation
 RedNote Search
500 Xiaohongshu notes / 30s

Copy to your AI assistant

zen-studio/douyin-live-recorder on Apify. Streams real-time chat/gift/like/join/viewer-count events from Douyin (抖音) live broadcasts as type-discriminated rows, with optional MP4 recording. Call ApifyClient("TOKEN").actor("zen-studio/douyin-live-recorder").call(run_input={...}), then client.dataset(run["defaultDatasetId"]).list_items().items. liveUrl accepts a live.douyin.com URL, share link, profile URL, or "auto". Full spec: GET https://api.apify.com/v2/acts/zen-studio~douyin-live-recorder/builds/default (Bearer TOKEN) → inputSchema, actorDefinition.storages.dataset, readme. Token: https://console.apify.com/account/integrations

Key Features

  • 15+ event types in real time — chat, gift, like, member join, follow, share, fansclub, emoji, viewer count, room stats, room ranking, room messages, stream adaptation, control signals
  • Optional MP4 recording — SD1, SD2, HD1, or Full HD segments uploaded to the key-value store every 1–60 minutes
  • Recording-only mode — set captureEvents: false to skip the event stream entirely and just save the MP4. You only pay for recording time
  • One row per event — polymorphic dataset, type is the discriminator. Filter chats with type = "chat", gifts with type = "gift", etc.
  • Pick the events you wantexcludeEvents lets you skip event types upfront (drop like if you only need chats and gifts, for example). Wire-noise types are filtered internally
  • Six input formats — paste a live.douyin.com URL, app share link, profile URL, UserSecID, numeric user id, or auto for a demo room
  • Reconnect-safe — capped exponential backoff; transient WS drops are recovered transparently and reflected in the summary's reconnect_count
  • Free tier — 5 lifetime runs, 5 minutes per run, recording disabled. No credit card required

How to Record Douyin Live Broadcasts

Basic — pick a currently-live demo room

{
"liveUrl": "auto",
"runTime": 5
}

Record a specific broadcast

{
"liveUrl": "https://live.douyin.com/376034101029",
"runTime": 60
}

Save the stream as MP4

{
"liveUrl": "https://live.douyin.com/376034101029",
"runTime": 30,
"recordVideo": true,
"videoQuality": "HD1",
"uploadEvery": 5
}

Resolve a broadcaster by profile URL

{
"liveUrl": "https://www.douyin.com/user/MS4wLjABAAAAY4cTwy_eXrFLF9JiUjt4QHb3-6c2vKE-bI0Xy_T2WCw",
"runTime": 60
}

Input Parameters

ParameterTypeDefaultDescription
liveUrlstring"auto"A Douyin live broadcast: live.douyin.com URL, bare numeric web id, v.douyin.com share link, profile URL, UserSecID, or numeric user id. Use auto for a demo room.
runTimeinteger0Minutes to stay connected. 0 = until the broadcaster ends the stream. Range 0–240.
captureEventsbooleantrueWhen off, the actor skips the chat / gift / like event stream entirely and only saves the MP4. Requires recordVideo: true.
excludeEventsarray[]Event types to drop from the dataset. Wire-noise types (system, stream_adaptation, connection_state) are filtered internally and never appear regardless of this setting.
recordVideobooleanfalseWhen on, the stream is recorded as MP4 segments and uploaded to the run's key-value store.
videoQualityenum"HD1"Recording quality: SD1, SD2, HD1, or FULL_HD1. Ignored when recordVideo is off.
uploadEveryinteger5Minutes per MP4 segment before rotation. Range 1–60. Set to 60 (or match runTime) for one consolidated file. Ignored when recordVideo is off.

What Data Can You Extract from Douyin Live Broadcasts?

Every run produces a polymorphic dataset. The first row is room_info, the last row is summary, and everything in between is one row per live event.

Per-event row types

  • chat — user nickname, fans-club name + level, pay-grade level, gender, full chat content
  • gift — gift name, diamond count, combo count, sender + recipient nicknames, total / repeat counts
  • like — sender, click count, room total
  • member — viewer who just joined, member count, enter type
  • social — follow / share actions, follow count
  • viewer_count — current viewers, total users, popularity, anchor-side breakdown
  • fansclub — fansclub event type and content
  • emoji_chat — emoji id and default text
  • room_stats — display labels (short / middle / long) and value
  • room_rank — top contributors with rank position
  • room_message — system top messages with biz scene
  • stream_adaptation — resolution / aspect-ratio changes during the stream
  • control — broadcaster status changes (status 3 = stream ended)

Output Example

[
{
"type": "room_info",
"room_id": "7644153789288680238",
"web_rid": "457647640330",
"broadcaster": { "nickname": "林悦" },
"title": "我是林悦,音乐的悦",
"user_count_text": "206",
"raw_url": "https://live.douyin.com/457647640330"
},
{
"type": "chat",
"msg_id": "7644159790989972516",
"room_id": "7644153789288680238",
"web_rid": "457647640330",
"user": {
"user_id": "4215971040468057",
"short_id": "33364754953",
"sec_uid": "MS4wLjABAAAAJ7L2GblVdXfdUjKx8g76iSv25rT3_3eiro_DxOXcFFms54WHBidCTpLgAR0HYFJ-",
"display_id": "12D798",
"nickname": "你若成风",
"gender": 1,
"fans_club_name": "悦悦有",
"fans_club_level": 13,
"pay_grade_level": 32
},
"content": "我好像认识你!"
},
{
"type": "gift",
"msg_id": "7644159811234567890",
"room_id": "7644153789288680238",
"web_rid": "457647640330",
"user": { "nickname": "热心观众", "pay_grade_level": 18 },
"gift_id": "12345",
"gift_name": "小心心",
"gift_diamond_count": 1,
"gift_describe": "送给主播一颗小心心",
"combo_count": 5,
"repeat_count": 5,
"total_count": 5,
"send_type": 1
},
{
"type": "like",
"user": { "nickname": "粉丝-A" },
"count": 3,
"total": 12847
},
{
"type": "member",
"user": { "nickname": "新观众" },
"member_count": 2225,
"enter_type": 1,
"action": 1
},
{
"type": "viewer_count",
"current_viewers": 2225,
"total_users": 48172,
"popularity": 9831,
"current_viewers_text": "2,225",
"total_users_text": "48,172"
},
{
"type": "room_stats",
"display_short": "人气",
"display_middle": "在线人气 2225",
"display_long": "当前在线人气 2225",
"display_value": 2225
},
{
"type": "room_rank",
"ranks": [
{ "rank": 1, "user": { "nickname": "榜一大哥" }, "score_text": "12.4w" },
{ "rank": 2, "user": { "nickname": "土豪二" }, "score_text": "8.1w" },
{ "rank": 3, "user": { "nickname": "粉丝三" }, "score_text": "5.6w" }
]
},
{
"type": "summary",
"room_id": "7644153789288680238",
"web_rid": "457647640330",
"capture_events": true,
"duration_seconds": 3600.0,
"produced_output": true,
"connection_opened": true,
"reconnect_count": 0,
"total_events": 28828,
"event_counts": {
"chat": 8420,
"like": 11230,
"member": 7104,
"gift": 982,
"viewer_count": 612,
"room_stats": 480
},
"recording_segments": 12,
"recording_total_bytes": 1283456789,
"recording_total_duration_s": 3597.4,
"recording_stop_reason": "deadline_reached",
"reason_for_exit": "runtime_cap",
"record_video_requested": true,
"record_video_effective": true,
"video_quality": "HD1"
}
]

Recording manifest (run OUTPUT)

The run's OUTPUT manifest is the canonical way to find the recordings. It always has the shape below — recordings is an empty array on runs that didn't capture any video:

{
"results": "https://api.apify.com/v2/datasets/.../items",
"recordings": [
{
"key": "recording_376034101029_0001.mp4",
"seq": 1,
"started_at_ms": 1779796533135,
"ended_at_ms": 1779796833135,
"duration_s": 300.0,
"bytes": 104857600,
"quality": "HD1",
"kv_url": "https://api.apify.com/v2/key-value-stores/.../records/recording_376034101029_0001.mp4"
}
]
}

Did the run succeed? (produced_output and reason_for_exit)

The summary row carries two fields that make it easy to filter for "this run delivered value":

  • produced_outputtrue iff at least one live event arrived OR at least one MP4 segment was uploaded. Use this as the canonical success filter across all three modes (events-only, events + recording, recording-only).
  • connection_opened — whether the live connection opened. Always false in recording-only mode by design. Use this when you specifically need to know about the event-stream side.

The reason_for_exit enum tells you why the run ended:

ValueMeaning
stream_endedThe broadcaster ended the stream (a control event with status: 3 was received).
runtime_capThe run hit your requested runTime and exited cleanly.
charge_limit_reachedA pay-per-event billing cap was reached.
recorder_failedThe recorder gave up — repeated stream-URL fetches, ffmpeg failures, or KV upload failures. The MP4 segments that did upload are still in the key-value store.
disconnect_unrecoverableThe live connection failed to reconnect after multiple attempts with zero events received.
transport_closedThe live connection closed for an unattributed reason.

Advanced Usage

Record until the broadcaster ends the stream

Set runTime: 0 and the actor stays connected until the broadcast ends. Apify's hard timeout of 4 hours still applies.

{
"liveUrl": "https://live.douyin.com/376034101029",
"runTime": 0
}

Recording-only mode (skip the event stream)

Save the broadcast as MP4 without paying for the event firehose. Useful when you only need video for later review or transcription. The dataset gets room_info + summary and nothing else; the run's OUTPUT manifest lists every recorded segment.

{
"liveUrl": "https://live.douyin.com/376034101029",
"runTime": 60,
"captureEvents": false,
"recordVideo": true,
"videoQuality": "HD1"
}

Free tier doesn't allow recording-only — recording is disabled on the free preview, so the run would do nothing.

High-bitrate archival capture

Pick the highest quality and short segments for granular replay.

{
"liveUrl": "https://live.douyin.com/376034101029",
"runTime": 120,
"recordVideo": true,
"videoQuality": "FULL_HD1",
"uploadEvery": 1
}

Pull viewer-count timeseries only

Skip every event except viewer counts. The dataset shrinks dramatically and only carries current_viewers, total_users, and popularity rows with ms-precise timestamps.

{
"liveUrl": "https://live.douyin.com/376034101029",
"runTime": 60,
"excludeEvents": [
"chat", "gift", "like", "member", "social",
"fansclub", "emoji_chat", "control",
"room_stats", "room_rank", "room_message"
]
}

Chat-and-gift focus

Drop everything except chat, gift, social (follows), and room ranks — the rows that matter for live-commerce analysis.

{
"liveUrl": "https://live.douyin.com/376034101029",
"runTime": 60,
"excludeEvents": [
"like", "member", "viewer_count",
"fansclub", "emoji_chat", "control",
"room_stats", "room_message"
]
}

Bulk-resolve a profile URL with an unknown room id

Paste the broadcaster's profile URL or numeric user id. The actor resolves to the current live room or fails cleanly if the broadcaster isn't streaming.

{
"liveUrl": "1929015166249580",
"runTime": 30
}

Pricing — Pay Per Event (PPE)

You only pay for connection time and recording time.

EventPer secondPer minute
Metadata seconds (event capture)$0.0015$0.09
Recording seconds (MP4)$0.00085$0.051

Cost Examples

RunMetadataRecordingTotal
10 minutes, events only$0.90~$0.90
30 minutes, events + HD recording$2.70$1.53~$4.23
60 minutes, events + HD recording$5.40$3.06~$8.46
60 minutes, recording-only at Full HD$3.06~$3.06

Free tier — 5 lifetime runs, 5 minutes per run, recording disabled. No credit card required. Use it to validate the event shape and decide if the pricing fits before scaling up.

Cost Optimization

  • Set runTime to bound the connection. Open-ended runs are easy to forget about.
  • Need MP4 only? Run with captureEvents: false, recordVideo: true — recording-only at $0.051/min is the cheapest mode (no metadata billing).
  • Need events only? Leave recordVideo: false — events-only at $0.09/min skips the recording cost.
  • Want both? Combined is ~$0.141/min ($8.46/hour).
  • Use SD1 / SD2 quality when the goal is archival, not playback fidelity.

FAQ

Which live broadcasts can I record? Any public Douyin (抖音) live broadcast. Paste a live.douyin.com URL, an app share link, a profile URL, a UserSecID, a numeric user id, or use auto for a demo room.

How fresh is the data? Every event is streamed in real time. Rows land in the dataset within seconds of the event firing in the live room.

What happens if the broadcaster goes offline mid-run? The actor emits a control row with status: 3 and then exits cleanly with reason_for_exit: "stream_ended" on the summary row.

What happens if the live connection drops temporarily? The actor reconnects with capped exponential backoff (2s, 4s, 8s, 16s, 30s). The summary's reconnect_count reflects how many drops happened during the run.

What happens if Apify migrates my run to a new host (long runs)? The actor detects the restart, writes a single migration_notice row to the dataset, preserves whatever MP4 segments did upload before the migration, and exits without re-doing work or re-billing. Re-trigger the run for a fresh, complete capture if you need uninterrupted coverage. Runs shorter than ~20 minutes rarely see migrations.

Can I filter the dataset by event type? Yes. The type column is the discriminator. Use type = "chat" for chat-only views, type = "gift" for tips, type = "viewer_count" for timeseries, and so on.

What's the free tier? 5 lifetime runs, capped at 5 minutes each, recording disabled. The cap resets only by upgrading to a paid plan.

How do I download the MP4 recordings? The run's OUTPUT manifest lists every segment with a kv_url. Each URL is a direct download for the MP4 file. Segment length is controlled by uploadEvery (1–60 minutes).

Can I record commercial / restricted broadcasts? The actor only attaches to publicly visible broadcasts. Private or password-gated rooms aren't accessible.

Why is metadata_seconds_charged 0 on my local run? Pay-per-event billing only fires on the Apify platform. Local runs and pre-publication runs show 0 here — the actor still emits everything, you just don't get charged.

Support

  • Bugs: Issues tab
  • Features: Issues tab

Extracts publicly available data from public live broadcasts. Users must comply with Douyin's terms of service and applicable data protection regulations (GDPR, CCPA). Do not record private, restricted, or copyright-protected content without authorization.


Real-time chat, gift, like, join, and viewer-count capture from Douyin (抖音) live broadcasts, with optional MP4 recording in SD–Full HD.