Skip to main content
TikTokLive provides built-in functionality to record livestreams directly to video files. This guide covers how to start, stop, and manage stream recordings.

Overview

The recording functionality allows you to:
  • Record livestreams to MP4 or other formats
  • Control recording start and stop times
  • Handle recordings automatically on disconnect
Recording livestreams may be subject to TikTok’s terms of service. Ensure you have permission to record content.

Basic Recording

1

Import required modules

import asyncio
from TikTokLive import TikTokLiveClient
from TikTokLive.events import ConnectEvent, DisconnectEvent
2

Create the client

client: TikTokLiveClient = TikTokLiveClient(
    unique_id="@username"
)
3

Start recording on connect

@client.on(ConnectEvent)
async def on_connect(event: ConnectEvent):
    # Start a recording
    client.web.fetch_video_data.start(
        output_fp=f"{event.unique_id}.mp4",
        room_info=client.room_info,
        output_format="mp4"
    )
4

Stop recording on disconnect

@client.on(DisconnectEvent)
async def on_disconnect(event: DisconnectEvent):
    if client.web.fetch_video_data.is_recording:
        client.web.fetch_video_data.stop()
5

Run with room_info enabled

if __name__ == '__main__':
    # Need room info to download stream
    client.run(fetch_room_info=True)

Complete Example

import asyncio

from TikTokLive.client.client import TikTokLiveClient
from TikTokLive.client.logger import LogLevel
from TikTokLive.events import ConnectEvent, DisconnectEvent

client: TikTokLiveClient = TikTokLiveClient(
    unique_id="@tv_asahi_news"
)


@client.on(ConnectEvent)
async def on_connect(event: ConnectEvent):
    client.logger.info("Connected!")

    # Start a recording
    client.web.fetch_video_data.start(
        output_fp=f"{event.unique_id}.mp4",
        room_info=client.room_info,
        output_format="mp4"
    )

    await asyncio.sleep(5)

    # Stop the client, we're done!
    await client.disconnect()


@client.on(DisconnectEvent)
async def on_live_end(_: DisconnectEvent):
    """Stop the download when we disconnect"""

    client.logger.info("Disconnected!")

    if client.web.fetch_video_data.is_recording:
        client.web.fetch_video_data.stop()


if __name__ == '__main__':
    # Enable download info
    client.logger.setLevel(LogLevel.INFO.value)

    # Need room info to download stream
    client.run(fetch_room_info=True)

Recording with Time Limit

Record for a specific duration:
import asyncio
from TikTokLive.events import ConnectEvent

@client.on(ConnectEvent)
async def on_connect(event: ConnectEvent):
    client.logger.info("Starting recording...")
    
    # Start recording
    client.web.fetch_video_data.start(
        output_fp=f"{event.unique_id}.mp4",
        room_info=client.room_info,
        output_format="mp4"
    )
    
    # Record for 5 minutes
    await asyncio.sleep(300)
    
    # Stop recording
    if client.web.fetch_video_data.is_recording:
        client.web.fetch_video_data.stop()
        client.logger.info("Recording stopped after 5 minutes")
    
    # Disconnect
    await client.disconnect()

Output Formats

You can specify different output formats:
# MP4 format (recommended)
client.web.fetch_video_data.start(
    output_fp="recording.mp4",
    room_info=client.room_info,
    output_format="mp4"
)

# FLV format
client.web.fetch_video_data.start(
    output_fp="recording.flv",
    room_info=client.room_info,
    output_format="flv"
)

# MKV format
client.web.fetch_video_data.start(
    output_fp="recording.mkv",
    room_info=client.room_info,
    output_format="mkv"
)
MP4 is the recommended format for best compatibility with video players and streaming platforms.

Checking Recording Status

You can check if a recording is active:
if client.web.fetch_video_data.is_recording:
    client.logger.info("Currently recording")
else:
    client.logger.info("Not recording")

Advanced: Conditional Recording

Start recording only when certain conditions are met:
from TikTokLive.events import ConnectEvent, RoomUserSeqEvent

min_viewers = 100
recording_started = False

@client.on(ConnectEvent)
async def on_connect(event: ConnectEvent):
    client.logger.info(f"Connected to @{event.unique_id}")

@client.on(RoomUserSeqEvent)
async def on_viewer_update(event: RoomUserSeqEvent):
    global recording_started
    
    viewer_count = event.total_user
    
    # Start recording when viewer count exceeds threshold
    if viewer_count >= min_viewers and not recording_started:
        client.logger.info(f"Starting recording - {viewer_count} viewers")
        
        client.web.fetch_video_data.start(
            output_fp=f"stream_{viewer_count}_viewers.mp4",
            room_info=client.room_info,
            output_format="mp4"
        )
        
        recording_started = True

File Naming Strategies

Timestamp-based naming

from datetime import datetime

@client.on(ConnectEvent)
async def on_connect(event: ConnectEvent):
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    filename = f"{event.unique_id}_{timestamp}.mp4"
    
    client.web.fetch_video_data.start(
        output_fp=filename,
        room_info=client.room_info,
        output_format="mp4"
    )

Organized directory structure

import os
from datetime import datetime

@client.on(ConnectEvent)
async def on_connect(event: ConnectEvent):
    # Create recordings directory
    recordings_dir = f"recordings/{event.unique_id}"
    os.makedirs(recordings_dir, exist_ok=True)
    
    # Generate filename with timestamp
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    filepath = f"{recordings_dir}/{timestamp}.mp4"
    
    client.web.fetch_video_data.start(
        output_fp=filepath,
        room_info=client.room_info,
        output_format="mp4"
    )

Error Handling

Handle recording errors gracefully:
@client.on(ConnectEvent)
async def on_connect(event: ConnectEvent):
    try:
        client.web.fetch_video_data.start(
            output_fp=f"{event.unique_id}.mp4",
            room_info=client.room_info,
            output_format="mp4"
        )
        client.logger.info("Recording started successfully")
        
    except Exception as e:
        client.logger.error(f"Failed to start recording: {e}")

@client.on(DisconnectEvent)
async def on_disconnect(_: DisconnectEvent):
    try:
        if client.web.fetch_video_data.is_recording:
            client.web.fetch_video_data.stop()
            client.logger.info("Recording stopped successfully")
            
    except Exception as e:
        client.logger.error(f"Error stopping recording: {e}")

Requirements

Recording requires fetch_room_info=True when connecting. Without room info, recording will fail.
# Correct - with room info
client.run(fetch_room_info=True)

# Won't work for recording
client.run()

Best Practices

  1. Always fetch room info - Use fetch_room_info=True when connecting
  2. Stop on disconnect - Always stop recording in the DisconnectEvent handler
  3. Check recording status - Use is_recording before stopping
  4. Handle errors - Wrap recording operations in try-except blocks
  5. Organize files - Use directories and timestamps for better organization
  6. Monitor disk space - Ensure sufficient storage for recordings

Storage Considerations

  • MP4 recordings can be large (1-5 GB per hour depending on quality)
  • Monitor available disk space before starting long recordings
  • Implement cleanup strategies for old recordings
  • Consider streaming to cloud storage for long-term archival

Build docs developers (and LLMs) love