🔧 はじめに:導入の背景と目的
最近、Flutterで開発中のiOSアプリに「1対1のリアルタイムビデオ通話機能」を追加することになりました。要件は以下の通り:
- ネイティブとのブリッジを最小限に抑えつつ、FlutterでUIを完結させたい
- 映像と音声の品質が高く、グローバルな通信でも安定すること
- 料金とドキュメントのバランスが良いSDKを選びたい
技術選定の結果、Tencent CloudのTRTC(Tencent Real-Time Communication)SDKがFlutter Pluginも提供しており、品質・コストのバランスも良いため、採用することにしました。
🔍 技術調査とTRTCを選んだ理由
他に検討した選択肢:
- WebRTC(自前実装):自由度は高いが、ネイティブとの連携やTURN設定が複雑
- Agora、Zoom SDK:使いやすいが、価格やプラグインのカスタマイズ性に課題あり
- TRTC:日本語対応こそ限定的だが、中国国内・APAC地域に強く、Flutter公式Pluginあり
TRTCの評価ポイント:
項目 | 内容 |
---|---|
SDK対応 | Flutter Pluginあり(iOS/Android共通) |
機能 | 通話、ライブ配信、録画、美顔、音量提示、画面共有など |
技術サポート | GitHub Issueと中国本家のフォーラム、または商用窓口あり |
コスト | 従量課金制で、試用枠も比較的広い |
📦 セットアップとFlutterプロジェクトの準備
1. pubspec.yamlの依存追加:
dependencies:
flutter:
sdk: flutter
trtc_cloud: ^1.0.4 # 最新はhttps://pub.dev/packages/trtc_cloud で確認
2. iOSのネイティブ設定(info.plist)
<key>NSCameraUsageDescription</key>
<string>カメラの使用が必要です</string>
<key>NSMicrophoneUsageDescription</key>
<string>マイクの使用が必要です</string>
3. Xcodeでの設定
- iOS Deployment Targetは
12.0
以上に設定 -
Runner.xcodeproj
>Build Settings
>Other Linker Flags
に-ObjC
を追加
🚀 TRTC接続実装:Flutterコード(iOS)
1. 初期化とローカルビデオ表示の準備
import 'package:flutter/material.dart';
import 'package:trtc_cloud/trtc_cloud.dart';
class CallPage extends StatefulWidget {
final int roomId;
final String userId;
final String userSig;
const CallPage({required this.roomId, required this.userId, required this.userSig});
@override
_CallPageState createState() => _CallPageState();
}
class _CallPageState extends State<CallPage> {
late TRTCCloud trtcCloud;
final int _localViewId = 1001;
final int _remoteViewId = 1002;
@override
void initState() {
super.initState();
_initTRTC();
}
Future<void> _initTRTC() async {
trtcCloud = TRTCCloud.sharedInstance();
await trtcCloud.startLocalPreview(true, _localViewId);
await trtcCloud.startLocalAudio(TRTCAudioQuality.TRTC_AUDIO_QUALITY_DEFAULT);
final params = TRTCParams(
sdkAppId: 1400000000, // TRTC.ioで取得
userId: widget.userId,
userSig: widget.userSig,
roomId: widget.roomId,
role: TRTCCloudDef.TRTCRoleAnchor,
);
await trtcCloud.enterRoom(params, TRTCCloudDef.TRTC_APP_SCENE_VIDEOCALL);
}
@override
void dispose() {
trtcCloud.exitRoom();
trtcCloud.stopLocalPreview();
trtcCloud.stopLocalAudio();
TRTCCloud.destroySharedInstance();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("TRTCビデオ通話")),
body: Stack(
children: [
TRTCCloudVideoView(viewId: _localViewId), // 自分の映像
Align(
alignment: Alignment.topRight,
child: SizedBox(
width: 120,
height: 160,
child: TRTCCloudVideoView(viewId: _remoteViewId), // 相手の映像
),
),
],
),
);
}
}
2. コールバック処理(例:リモートユーザーが入室したとき)
trtcCloud.registerListener((type, param) {
if (type == TRTCCloudListener.onUserVideoAvailable) {
final userId = param["userId"];
final available = param["available"];
if (available) {
trtcCloud.startRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, _remoteViewId);
} else {
trtcCloud.stopRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG);
}
}
});
✅ 実機テスト結果
テスト環境 | 結果 |
---|---|
iPhone 12(4G) | 映像・音声ともに滑らか |
iPhone SE(WiFi) | 通信状態によって300msの遅延あり |
Androidとの通信 | Flutterプラグインで問題なし |
弱点:
- 接続エラー時のログがやや分かりづらい(Flutter側に詳細出ない)
-
userSig
の生成が手動だと煩雑(→ 自動生成用にサーバ側実装を検討)
📝 まとめ
TRTCのFlutterプラグインを用いたiOSでの導入は、FlutterのUI資産を活かしつつ、比較的簡潔に音声・映像通話機能を追加できました。日本語での情報がまだ少ないため、この日記が今後導入を検討する開発者の参考になれば幸いです。
今後追加予定の機能:
- 通話中のネットワーク品質監視
- 通話中の録画(Cloud Recording API)
- スクリーン共有やドキュメント表示との連携