Capability | Description |
Two methods of stream creation | AssetVirtualmanKey (Asset ID), VirtualmanProjectId (Digital Human Project ID) |
Three types of streaming protocols | RTMP,TRTC,WebRTC |
Two drive modes | text-driven (input text to make Digital Human speak), audio-driven (upload audio files to drive lip-sync movements) |
H5 video playback | TRTC and WebRTC protocols automatically pop up the browser playback page. |
├── tencent_virtual_human_completeV1.py # Main script (Python)├── trtc_player.html # TRTC protocol H5 playback page├── webrtc_player.html # WebRTC protocol H5 playback page└── TcPlayer-2.4.5.js # TCPlayerLite SDK (WebRTC playback dependency)
pip install requests websocket-client pydub
# macOSbrew install ffmpeg# Ubuntu/Debiansudo apt install ffmpeg# Windows# Download https://ffmpeg.org/download.html and add it to PATH
Parameters | Description | Obtaining Method |
appkey | Application Identifier | Digital Human Platform → Application Management (Refer to Figure 1) |
accesstoken | Access Token | Digital Human Platform → Application Management (Refer to Figure 1) |
asset_virtualman_key | Avatar Asset ID | Digital Human Platform → Image Asset Management (Refer to Figure 2) |
virtualman_project_id | Digital Human Project ID | Digital Human Platform → Project Management |
asset_virtualman_key and virtualman_project_id represent two different stream creation methods. When using, you can choose one of the two options.



CONFIG dictionary at the bottom of the tencent_virtual_human_completeV1.py file:CONFIG = {"appkey": "your_appkey","accesstoken": "your_accesstoken","asset_virtualman_key": "your_asset_key", # Image Asset ID (preferred)"virtualman_project_id": "", # Project ID (used when asset_key is empty)"protocol": "rtmp", # Streaming protocol: "rtmp" / "trtc" / "webrtc""protocol_option": None, # Protocol option (see Section 5)}
Operating System: Ubuntu 24.04.3 LTS / x86_64
Runtime Version: Python 3.11.1
python tencent_virtual_human_completeV1.py
1️⃣ Create a session (automatically select the stream creation method)2️⃣ Wait for session readiness (polling status, maximum 120 seconds)3️⃣ Enable session🎬 Automatically launch the H5 player (for TRTC/WebRTC protocols)4️⃣ Create WebSocket connection5️⃣ Enter interactive mode6️⃣ Close session
📋 Driver mode selection:1 - text-driven (input text to make Digital Humans speak)2 - audio-driven (selecting audio files to drive the Digital Human)q - Exit
1: Enter text-driven mode. After text is inputted, the Digital Human will use TTS to synthesize speech and synchronize lip-sync.2: Enter audio-driven mode. Enter the audio file path (supports formats such as mp3, wav), and the Digital Human will use your audio to drive the lip-sync.q: Exit and close the session./v2/ivh/sessionmanager/sessionmanagerservice/createsessionbyassetCONFIG = {"asset_virtualman_key": "your_asset_key","virtualman_project_id": "", # Leave blank}
Operating System: Ubuntu 24.04.3 LTS / x86_64
Runtime Version: Python 3.11.1
/v2/ivh/sessionmanager/sessionmanagerservice/createsessionCONFIG = {"asset_virtualman_key": "", # Leave blank"virtualman_project_id": "your_project_id",}
Operating System: Ubuntu 24.04.3 LTS / x86_64
Runtime Version: Python 3.11.1
create_session():def create_session(self) -> Tuple[bool, str]:if self.asset_virtualman_key:return self.create_session_by_asset() # Priorityelif self.virtualman_project_id:return self.create_session_by_project() # Fallbackelse:return False, "Both parameters are empty, unable to create stream"
Protocol | Delay | Playback Method | Scenarios |
RTMP protocol | 2-5 seconds | VLC and other external players | Common scenarios, highest compatibility |
TRTC protocol | 200~400ms | Automatically pop up the H5 page (TRTC Web SDK) | Ultra-low latency real-time interaction |
WebRTC protocol | 500ms-1s | Automatically pop up the H5 page (TCPlayerLite) | Low-latency Web playback |
CONFIG = {"protocol": "rtmp","protocol_option": None,}
rtmp://liveplay.ivh.qq.com/live/m789. It can be opened using players like VLC.# Debug Mode (using the platform-unified AppId, no additional configuration required)CONFIG = {"protocol": "trtc","protocol_option": None,}
trtc:// format playback URL is returned, and the script automatically:trtc:// address.trtc_player.html playback page in the browser;CONFIG = {"protocol": "webrtc","protocol_option": None,}
webrtc:// format playback URL is returned, and the script automatically:webrtc_player.html playback page in the browser;ProtocolOption is used for TRTC production environments or custom streaming scenarios.Field | Type | Description |
TrtcUseExternalApp | bool | Whether to use an external TRTC AppId |
TrtcAppId | str | TRTC AppId (mandatory when an external AppId is used) |
TrtcRoomId | int | TRTC digital room ID |
TrtcStrRoomId | str | TRTC string room ID (choose one of the two options with TrtcRoomId) |
TrtcAutoGenRoomIdType | int | Auto-generated room ID type: 0=number (default), 1=string |
TrtcUserSig | str | TRTC user signature (mandatory when an external AppId is used) |
TrtcPrivateMapKey | str | TRTC permission ticket (enter "dummy" if advanced permissions are not enabled) |
CssCustomPushUrl | str | Custom CSS push URL (any protocol can be used) |
CONFIG = {"protocol": "trtc","protocol_option": {"TrtcUseExternalApp": True,"TrtcAppId": "1400xxxxxx","TrtcRoomId": 12345,"TrtcUserSig": "eJw8js0Kgk...","TrtcPrivateMapKey": "dummy"},}
CONFIG = {"protocol": "rtmp","protocol_option": {"CssCustomPushUrl": "rtmp://domain/appName/streamName?txSecret={0}&txTime={1}"},}
"ExtraInfo": {"AlphaChannelEnable":True} # Enable Alpha channel (if transparent background is required)
appId, roomId, userId, and userSig from URL parameters.role: 'audience').REMOTE_VIDEO_AVAILABLE event and automatically pull the remote video stream.object-fit: contain to be displayed in its entirety.// Enter the room (pull stream only as audience, no pushing)await trtc.enterRoom({sdkAppId: config.appId,userId: config.userId,userSig: config.userSig,roomId: config.roomId,scene: 'live',role: 'audience'});// Listen for and play remote videotrtc.on(TRTC.EVENT.REMOTE_VIDEO_AVAILABLE, async (event) => {await trtc.startRemoteVideo({userId: event.userId,streamType: event.streamType,view: 'remote-video',option: { objectFit: 'contain' }});});
http://localhost:8080/trtc_player.html?appId=1400695865&roomId=402183450&userId=user_xxx&userSig=eJw8...&virtualManUserId=402183450_ivh_anchor
TcPlayer-2.4.5.js)?url=webrtc://...player = new TcPlayer('player-container', {"webrtc": webrtcUrl,"width": '100%',"height": '540',"autoplay": true,"live": true,"controls": "none","webrtcConfig": {"streamType": "auto"},"listener": function (msg) {handlePlayerEvent(msg);}});
http://localhost:8080/webrtc_player.html?url=webrtc://liveplay.ivh.qq.com/live/m11533590420520971383?min_delay_ms=100
file:// protocol is not supported).key1=value1&key2=value2&...accesstoken as the key to compute the signature;def _generate_signature(self, parameters: Dict[str, str]) -> str:sorted_params = sorted(parameters.items())signing_content = '&'.join(f'{k}={v}' for k, v in sorted_params)h = hmac.new(self.accesstoken.encode('utf-8'),signing_content.encode('utf-8'),hashlib.sha256)hash_in_base64 = base64.b64encode(h.digest()).decode('utf-8')return quote(hash_in_base64)
┌─────────────┐│ Create session │ create_session()└──────┬──────┘▼┌─────────────┐│ Wait for readiness │ wait_for_session_ready() ← Poll SessionStatus└──────┬──────┘ SessionStatus=3 → Preparing▼ SessionStatus=1 → Ready┌─────────────┐│ Enable session │ start_session()└──────┬──────┘▼┌─────────────┐│ H5 Player │ start_h5_player() ← Automatically launched for TRTC/WebRTC└──────┬──────┘▼┌─────────────┐│ WebSocket │ create_websocket_connection()│ Persistent connection channel │└──────┬──────┘▼┌─────────────┐│ Interactive Drive │ send_text_drive() / send_audio_drive()│ (Loop) │└──────┬──────┘▼┌─────────────┐│ Close session │ close_session()└─────────────┘
drive_cmd = {"Header": {},"Payload": {"ReqId": req_id,"SessionId": self.session_id,"Command": "SEND_TEXT","Data": {"Text": "Hello, welcome to Tencent Cloud Digital Human Platform","ChatCommand": "NotUseChat"}}}self.ws.send(json.dumps(drive_cmd, ensure_ascii=False))
audio = AudioSegment.from_file(audio_file_path)audio = audio.set_channels(1).set_frame_rate(16000).set_sample_width(2)pcm_data = audio.raw_data
IsFinal: True_ffmpeg_path = shutil.which('ffmpeg')
object-fit: contain. If issues persist, check whether the browser is the latest version.TcPlayer-2.4.5.js file is in the same directory as webrtc_player.htmlfile:// protocol.start_h5_player() function's h5_port parameter:h5_url = self.start_h5_player(h5_port=9090)
Was this page helpful?
You can also Contact sales or Submit a Ticket for help.
Help us improve! Rate your documentation experience in 5 mins.
Feedback