tencent_rtc_sdk 13.5.2 copy "tencent_rtc_sdk: ^13.5.2" to clipboard
tencent_rtc_sdk: ^13.5.2 copied to clipboard

A powerful real-time SDK for Video Calling and Live Video Streaming. Delivers ultra-low latency and crystal-clear audio/video via​ a simple API for quick integration.

example/example.md

import 'dart:async';
import 'dart:io' show Platform;
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:tencent_rtc_sdk/trtc_cloud.dart';
import 'package:tencent_rtc_sdk/trtc_cloud_def.dart';
import 'package:tencent_rtc_sdk/trtc_cloud_listener.dart';
import 'package:tencent_rtc_sdk/trtc_cloud_video_view.dart';

// Fill in your own TRTC credentials
const sdkAppId = 0; // "<-- Insert SDKAppID -->"
const userSig = ""; // "<-- Insert UserSig -->"
const roomId = 123456; // "<-- Insert Room ID -->"

/// Room entry status
enum _RoomStatus { joining, success, failed, hidden }

/// A basic TRTC video call example.
class SimpleDemoPage extends StatefulWidget {
  const SimpleDemoPage({Key? key}) : super(key: key);

  @override
  State<SimpleDemoPage> createState() => _SimpleDemoPageState();
}

class _SimpleDemoPageState extends State<SimpleDemoPage> {
  static const Color _bgColor = Color(0xFF1A2433);
  static const Color _placeholderColor = Color(0xFF243447);

  // Local user ID (random)
  final String _userId = 'user_${100000 + Random().nextInt(900000)}';

  TRTCCloud? _trtcCloud;
  TRTCCloudListener? _listener;

  bool _initialized = false;
  bool _isCameraOn = true;
  bool _isMicOn = true;
  bool _isSpeakerOn = true;
  String? _remoteUserId;

  _RoomStatus _roomStatus = _RoomStatus.joining;
  int _enterRoomResult = 0;
  Timer? _statusTimer;

  @override
  void initState() {
    super.initState();
    _initAndEnter();
  }

  Future<void> _initAndEnter() async {
    // Request camera / microphone permissions before entering the room.
    if (Platform.isAndroid || Platform.isIOS) {
      await [Permission.microphone, Permission.camera].request();
    }

    debugPrint('[demo] Initializing engine…');
    _trtcCloud = await TRTCCloud.sharedInstance();
    debugPrint('[demo] sharedInstance ready');
    _listener = TRTCCloudListener(
      onEnterRoom: (result) {
        debugPrint('onEnterRoom: $result');
        if (!mounted) return;
        setState(() {
          _enterRoomResult = result;
          _roomStatus = result > 0 ? _RoomStatus.success : _RoomStatus.failed;
        });
        if (result > 0) {
          _statusTimer?.cancel();
          _statusTimer = Timer(const Duration(seconds: 3), () {
            if (mounted) setState(() => _roomStatus = _RoomStatus.hidden);
          });
        }
      },
      onUserVideoAvailable: (userId, available) {
        if (!mounted) return;
        setState(() => _remoteUserId = available ? userId : null);
      },
      onRemoteUserLeaveRoom: (userId, reason) {
        if (!mounted) return;
        if (_remoteUserId == userId) {
          setState(() => _remoteUserId = null);
        }
      },
      onError: (errCode, errMsg) => debugPrint('onError: $errCode $errMsg'),
    );
    _trtcCloud!.registerListener(_listener!);

    _trtcCloud!.enterRoom(
      TRTCParams(
        sdkAppId: sdkAppId,
        userId: _userId,
        userSig: userSig,
        roomId: roomId,
        role: TRTCRoleType.anchor,
      ),
      TRTCAppScene.videoCall,
    );

    _trtcCloud!.startLocalAudio(TRTCAudioQuality.speech);

    if (mounted) {
      setState(() => _initialized = true);
    }
  }

  // Toggle the local camera
  void _toggleCamera() {
    setState(() => _isCameraOn = !_isCameraOn);
    _trtcCloud?.muteLocalVideo(TRTCVideoStreamType.big, !_isCameraOn);
  }

  // Toggle the local microphone
  void _toggleMic() {
    setState(() => _isMicOn = !_isMicOn);
    _trtcCloud?.muteLocalAudio(!_isMicOn);
  }

  // Toggle the speaker on / off
  void _toggleSpeaker() {
    setState(() => _isSpeakerOn = !_isSpeakerOn);
    // mute = true stops playing back all remote audio
    _trtcCloud?.muteAllRemoteAudio(!_isSpeakerOn);
  }

  @override
  void dispose() {
    _statusTimer?.cancel();
    if (_listener != null) {
      _trtcCloud?.unRegisterListener(_listener!);
    }
    _trtcCloud?.stopLocalPreview();
    _trtcCloud?.stopLocalAudio();
    _trtcCloud?.exitRoom();
    TRTCCloud.destroySharedInstance();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: _bgColor,
      appBar: AppBar(
        elevation: 0,
        backgroundColor: _bgColor,
        foregroundColor: Colors.white,
        centerTitle: false,
        title: const Text(
          'TRTC Video Call',
          style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
        ),
      ),
      body: Stack(
        children: [
          Positioned.fill(child: _remoteVideo()),
          Positioned(top: 12, left: 0, right: 0, child: _roomStatusBanner()),
          Positioned(top: 12, left: 16, child: _localVideo()),
          Positioned(left: 0, right: 0, bottom: 0, child: _controlBar()),
        ],
      ),
    );
  }

  // Room entry status banner
  Widget _roomStatusBanner() {
    if (_roomStatus == _RoomStatus.hidden) return const SizedBox.shrink();
    final (String text, Color color) = switch (_roomStatus) {
      _RoomStatus.joining => ('Joining…', Colors.amber),
      _RoomStatus.success => ('Joined', Colors.green),
      _RoomStatus.failed => ('Failed to enter room (code: $_enterRoomResult)', Colors.redAccent),
      _RoomStatus.hidden => ('', Colors.transparent),
    };
    return Center(
      child: Container(
        padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
        decoration: BoxDecoration(
          color: Colors.black.withOpacity(0.6),
          borderRadius: BorderRadius.circular(20),
        ),
        child: Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            Icon(
              _roomStatus == _RoomStatus.success
                  ? Icons.check_circle
                  : (_roomStatus == _RoomStatus.failed
                      ? Icons.error
                      : Icons.hourglass_top),
              color: color,
              size: 18,
            ),
            const SizedBox(width: 8),
            Text(
              text,
              style: const TextStyle(color: Colors.white, fontSize: 14),
            ),
          ],
        ),
      ),
    );
  }

  // Local preview window (rounded card)
  Widget _localVideo() {
    return ClipRRect(
      borderRadius: BorderRadius.circular(12),
      child: Container(
        width: 110,
        height: 150,
        color: _placeholderColor,
        child: !_initialized
            ? const Center(
                child: SizedBox(
                  width: 20,
                  height: 20,
                  child: CircularProgressIndicator(
                      strokeWidth: 2, color: Colors.white54),
                ),
              )
            : Stack(
                children: [
                  Positioned.fill(
                    child: TRTCCloudVideoView(
                      onViewCreated: (viewId) {
                        debugPrint('[demo] Local preview view created, viewId: $viewId');
                        // Call startLocalPreview once, then sync the current mute state
                        _trtcCloud?.startLocalPreview(true, viewId);
                        _trtcCloud?.muteLocalVideo(
                            TRTCVideoStreamType.big, !_isCameraOn);
                        debugPrint('[demo] startLocalPreview called');
                      },
                    ),
                  ),
                  if (!_isCameraOn)
                    Positioned.fill(
                      child: Container(
                        color: Colors.black.withOpacity(0.6),
                        child: const Center(
                          child:
                              Icon(Icons.videocam_off, color: Colors.white70),
                        ),
                      ),
                    ),
                ],
              ),
      ),
    );
  }

  Widget _remoteVideo() {
    if (_remoteUserId == null) {
      return const Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Icon(Icons.videocam_off_outlined, size: 64, color: Colors.white38),
            SizedBox(height: 16),
            Text(
              'Waiting for remote user…',
              style: TextStyle(color: Colors.white54, fontSize: 16),
            ),
          ],
        ),
      );
    }
    return Stack(
      children: [
        Positioned.fill(
          child: TRTCCloudVideoView(
            key: Key(_remoteUserId!),
            onViewCreated: (viewId) {
              _trtcCloud?.startRemoteView(
                _remoteUserId!,
                TRTCVideoStreamType.big,
                viewId,
              );
            },
          ),
        ),
      ],
    );
  }

  Widget _controlBar() {
    return Container(
      margin: const EdgeInsets.fromLTRB(20, 0, 20, 20),
      padding: const EdgeInsets.symmetric(vertical: 14),
      decoration: BoxDecoration(
        color: Colors.white.withOpacity(0.08),
        borderRadius: BorderRadius.circular(28),
        border: Border.all(color: Colors.white.withOpacity(0.1)),
      ),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          _roundButton(
            icon: _isCameraOn ? Icons.videocam : Icons.videocam_off,
            label: 'Camera',
            active: _isCameraOn,
            onTap: _toggleCamera,
          ),
          _roundButton(
            icon: _isMicOn ? Icons.mic : Icons.mic_off,
            label: 'Mic',
            active: _isMicOn,
            onTap: _toggleMic,
          ),
          _roundButton(
            icon: _isSpeakerOn ? Icons.volume_up : Icons.volume_off,
            label: _isSpeakerOn ? 'Speaker on' : 'Speaker off',
            active: _isSpeakerOn,
            onTap: _toggleSpeaker,
          ),
        ],
      ),
    );
  }

  Widget _roundButton({
    required IconData icon,
    required String label,
    required VoidCallback onTap,
    required bool active,
    Color? background,
  }) {
    final Color bg = background ?? (active ? Colors.white : Colors.white24);
    final Color fg = active ? const Color(0xFF121212) : Colors.white70;
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        Material(
          color: bg,
          shape: const CircleBorder(),
          child: InkWell(
            customBorder: const CircleBorder(),
            onTap: onTap,
            child: SizedBox(
              width: 56,
              height: 56,
              child: Icon(icon, color: fg, size: 26),
            ),
          ),
        ),
        const SizedBox(height: 8),
        Text(label,
            style: const TextStyle(color: Colors.white70, fontSize: 12)),
      ],
    );
  }
}
12
likes
140
points
10.2k
downloads

Documentation

API reference

Publisher

verified publishertrtc.io

Weekly Downloads

A powerful real-time SDK for Video Calling and Live Video Streaming. Delivers ultra-low latency and crystal-clear audio/video via​ a simple API for quick integration.

Homepage
Repository (GitHub)
View/report issues

Topics

#webrtc #audio #video #voip #live-streaming

License

Apache-2.0 (license)

Dependencies

ffi, flutter, json_annotation, plugin_platform_interface, super_player

More

Packages that depend on tencent_rtc_sdk

Packages that implement tencent_rtc_sdk