Skip to content

Flutter

这页只覆盖客户端单端视角,目标是尽快跑通“引用 SDK -> 初始化 -> 连接并播放”。

前置条件

环境要求

项目要求
Flutter>=3.13.0
Dart>=3.1.0 <4.0.0
支持平台Android / iOS / macOS

1. 引用 SDK

yaml
dependencies:
  flutter:
    sdk: flutter
  tirtc_av: ^<latest-version>

版本号从Flutter SDK 发布说明获取。

2. 初始化 SDK

dart
Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // 应用启动时初始化一次。
  await TiRtc.initialize();
  runApp(
    MaterialApp(
      home: PlayerPage(
        remoteId: 'your-remote-id',
        token: 'v1.xxxxxx', // got from backend
        audioStreamId: yourAudioStreamId,
        videoStreamId: yourVideoStreamId,
      ),
    ),
  );
}

3. 连接并播放

这份 quick start 按“连上就发”策略保持最短路径。如果你的设备端采用“收到订阅再发”,连接进入 TiRtcConnState.connected 后再调用 conn.subscribeAudio(streamId: audioStreamId)conn.subscribeVideo(streamId: videoStreamId),页面离开前再调用 conn.unsubscribeAudio(streamId: audioStreamId)conn.unsubscribeVideo(streamId: videoStreamId)

dart
class PlayerPage extends StatefulWidget {
  const PlayerPage({
    super.key,
    required this.remoteId,
    required this.token,
    required this.audioStreamId,
    required this.videoStreamId,
  });

  final String remoteId;
  final String token;
  final int audioStreamId;
  final int videoStreamId;

  @override
  State<PlayerPage> createState() => _PlayerPageState();
}

class _PlayerPageState extends State<PlayerPage> {
  static const String tag = 'TiRtcQuickStart';

  final conn = TiRtcConn();
  final audioOutput = TiRtcAudioOutput();
  final videoOutput = TiRtcVideoOutput();

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

    // 打印基础状态,便于先定位黑屏、无声或断连。
    conn.onStateChanged = (state) {
      debugPrint('$tag conn state=$state');
    };
    conn.onDisconnected = (code) {
      debugPrint('$tag conn disconnected code=$code');
    };
    conn.onError = (code) {
      debugPrint('$tag conn error code=$code');
    };
    audioOutput.onStateChanged = (state) {
      debugPrint('$tag audio state=$state');
    };
    audioOutput.onError = (code) {
      debugPrint('$tag audio error code=$code');
    };
    videoOutput.onStateChanged = (state) {
      debugPrint('$tag video state=$state');
    };
    videoOutput.onRenderSizeChanged = (size) {
      debugPrint('$tag video size=${size.width}x${size.height}');
    };
    videoOutput.onError = (code) {
      debugPrint('$tag video error code=$code');
    };

    // 绑定要播放的远端音视频流,再发起连接。
    audioOutput.attach(
      connection: conn,
      streamId: widget.audioStreamId,
    );
    videoOutput.attach(
      connection: conn,
      streamId: widget.videoStreamId,
    );
    final int code = conn.connect(
      remoteId: widget.remoteId,
      token: widget.token,
    );
    if (code != 0) {
      debugPrint('$tag connect request failed code=$code');
    }
  }

  @override
  void dispose() {
    // 页面销毁时释放对象。
    videoOutput.detach();
    videoOutput.dispose();
    audioOutput.detach();
    audioOutput.dispose();
    conn.disconnect();
    conn.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: AspectRatio(
          aspectRatio: 16 / 9,
          child: videoOutput.view(),
        ),
      ),
    );
  }
}

Ti RTC 开发文档