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
Import required modules
import asyncio
from TikTokLive import TikTokLiveClient
from TikTokLive.events import ConnectEvent, DisconnectEvent
Create the client
client: TikTokLiveClient = TikTokLiveClient(
unique_id="@username"
)
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"
)
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()
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()
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
- Always fetch room info - Use
fetch_room_info=True when connecting
- Stop on disconnect - Always stop recording in the
DisconnectEvent handler
- Check recording status - Use
is_recording before stopping
- Handle errors - Wrap recording operations in try-except blocks
- Organize files - Use directories and timestamps for better organization
- 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