TikTokLive allows you to download profile images and avatars directly from event data. This is useful for creating custom overlays, user galleries, or archiving user information.
Overview
User profile images are available in most events that include user data, such as:
CommentEvent - Comments in chat
GiftEvent - Gift senders
JoinEvent - Users joining the stream
FollowEvent - New followers
Basic Image Download
Import required modules
from TikTokLive import TikTokLiveClient
from TikTokLive.events import CommentEvent, ConnectEvent
Create the client
client: TikTokLiveClient = TikTokLiveClient(
unique_id="@username"
)
Add event handler with image download
@client.on(CommentEvent)
async def on_comment(event: CommentEvent):
# Download the image
image_bytes: bytes = await client.web.fetch_image_data(
image=event.user.avatar_thumb
)
# Write to file
with open(f"{event.user.unique_id}.webp", "wb") as file:
file.write(image_bytes)
client.logger.info("Downloaded an image!")
Complete Example
from TikTokLive.client.client import TikTokLiveClient
from TikTokLive.client.logger import LogLevel
from TikTokLive.events import ConnectEvent, CommentEvent
client: TikTokLiveClient = TikTokLiveClient(
unique_id="@tv_asahi_news"
)
@client.on(ConnectEvent)
async def on_connect(event: ConnectEvent):
client.logger.info(f"Connected to @{event.unique_id}!")
@client.on(CommentEvent)
async def on_comment(event: CommentEvent):
client.logger.info("Received a comment!")
# Download the image
image_bytes: bytes = await client.web.fetch_image_data(
image=event.user.avatar_thumb
)
# Write to bytes
with open(f"{event.user.unique_id}.webp", "wb") as file:
file.write(image_bytes)
client.logger.info("Downloaded an image!")
if __name__ == '__main__':
# Enable debug info
client.logger.setLevel(LogLevel.INFO.value)
# Connect
client.run(process_connect_events=False)
Available Image Types
User objects typically contain multiple image URLs:
@client.on(CommentEvent)
async def on_comment(event: CommentEvent):
# Thumbnail (small, square)
avatar_thumb = event.user.avatar_thumb
# Medium size avatar
avatar_medium = event.user.avatar_medium
# Large avatar
avatar_large = event.user.avatar_large
# Download the large version
image_bytes = await client.web.fetch_image_data(
image=avatar_large
)
Downloading from Different Events
From Gift Events
from TikTokLive.events import GiftEvent
@client.on(GiftEvent)
async def on_gift(event: GiftEvent):
# Download gift sender's avatar
image_bytes = await client.web.fetch_image_data(
image=event.user.avatar_thumb
)
with open(f"gifts/{event.user.unique_id}.webp", "wb") as file:
file.write(image_bytes)
From Join Events
from TikTokLive.events import JoinEvent
@client.on(JoinEvent)
async def on_join(event: JoinEvent):
# Download new viewer's avatar
image_bytes = await client.web.fetch_image_data(
image=event.user.avatar_thumb
)
with open(f"viewers/{event.user.unique_id}.webp", "wb") as file:
file.write(image_bytes)
Advanced Usage
Caching Images
Avoid downloading the same image multiple times:
import os
from TikTokLive.events import CommentEvent
downloaded_users = set()
@client.on(CommentEvent)
async def on_comment(event: CommentEvent):
user_id = event.user.unique_id
# Skip if already downloaded
if user_id in downloaded_users:
return
# Check if file exists
filepath = f"avatars/{user_id}.webp"
if os.path.exists(filepath):
downloaded_users.add(user_id)
return
# Download image
image_bytes = await client.web.fetch_image_data(
image=event.user.avatar_thumb
)
# Create directory if needed
os.makedirs("avatars", exist_ok=True)
# Save image
with open(filepath, "wb") as file:
file.write(image_bytes)
downloaded_users.add(user_id)
client.logger.info(f"Downloaded avatar for {user_id}")
Processing Images
You can process images using PIL/Pillow:
from PIL import Image
from io import BytesIO
from TikTokLive.events import CommentEvent
@client.on(CommentEvent)
async def on_comment(event: CommentEvent):
# Download image
image_bytes = await client.web.fetch_image_data(
image=event.user.avatar_thumb
)
# Open with PIL
image = Image.open(BytesIO(image_bytes))
# Resize to 128x128
image = image.resize((128, 128))
# Convert to PNG
image.save(f"{event.user.unique_id}.png", "PNG")
Install Pillow first: pip install Pillow
TikTok profile images are typically served in WebP format, which offers good compression and quality.
To convert to other formats:
from PIL import Image
from io import BytesIO
image_bytes = await client.web.fetch_image_data(
image=event.user.avatar_thumb
)
image = Image.open(BytesIO(image_bytes))
image.save(f"{event.user.unique_id}.jpg", "JPEG")
image.save(f"{event.user.unique_id}.png", "PNG")
Error Handling
Always handle potential download errors:
@client.on(CommentEvent)
async def on_comment(event: CommentEvent):
try:
image_bytes = await client.web.fetch_image_data(
image=event.user.avatar_thumb
)
with open(f"{event.user.unique_id}.webp", "wb") as file:
file.write(image_bytes)
except Exception as e:
client.logger.error(f"Failed to download image: {e}")
Ensure you have proper error handling, as network issues or invalid URLs can cause download failures.
Best Practices
- Create directories - Use
os.makedirs("path", exist_ok=True) before saving files
- Cache downloads - Don’t download the same image multiple times
- Handle errors - Network issues can occur, always use try-except blocks
- Use unique filenames - Base filenames on
unique_id to avoid conflicts
- Clean up old files - Implement a cleanup strategy for old images