0.5 C
New York
Sunday, January 12, 2025

flutter – Agora_rtc digicam isnot work on ios machine


I am making an attempt to construct a video calling function in my Flutter app utilizing Agora.

i’m making an attempt to make use of agora_rtc for video name , the black half above is digicam the place use can see him self, this function works will on anroid however in ios seem black display screen and no digicam opened
i setup all permissions for each ios and android anybody can assist me with thatenter picture description right here
My code is as follows:

import 'bundle:flutter/basis.dart';
import 'bundle:agora_rtc_engine/agora_rtc_engine.dart';
import 'bundle:permission_handler/permission_handler.dart';
import 'dart:async';
import 'bundle:flutter_svg/flutter_svg.dart';
class VideoChatWidget extends StatefulWidget {
  const VideoChatWidget({
    tremendous.key,
    this.width,
    this.peak,
    required this.channelName,
    required this.appId,
    required this.token,
    required this.userData,
  });

  closing double? width;
  closing double? peak;
  closing String channelName;
  closing String appId;
  closing String token;
  closing ChatsStruct userData;

  @override
  State createState() => _VideoChatWidgetState();
}

class _VideoChatWidgetState extends State {
  bool isCameraOff = false;
  bool isMuted = false;
  late RtcEngine _engine;
  bool _localUserJoined = true;
  int? _remoteUid;
  Timer? _callTimer;
  Length _callDuration = Length(seconds: 0);

  @override
  void initState() {
    tremendous.initState();
    initializeAgora();
    _startCallTimer();
  }

  Future initializeAgora() async {
    if (!kIsWeb) {
      closing permissions =
          await [Permission.microphone, Permission.camera].request();
      if (permissions.values
          .any((standing) => standing != PermissionStatus.granted)) {
        print("Permissions not granted");
        return;
      }
    }

    print('🚀 Initializing Agora');
    attempt {
      _engine = createAgoraRtcEngine();
      await _engine.initialize(RtcEngineContext(
        appId: widget.appId,
        channelProfile: ChannelProfileType.channelProfileLiveBroadcasting,
      ));
      print('✅ Agora Engine Initialized');

      await _engine.enableVideo();
      await _engine.startPreview(); // Begin native video preview

      await _engine.joinChannel(
        token: widget.token,
        channelId: widget.channelName,
        uid: 0,
        choices: const ChannelMediaOptions(
          clientRoleType: ClientRoleType.clientRoleBroadcaster,
          channelProfile: ChannelProfileType.channelProfileCommunication,
        ),
      );

      print('✅ Joined Channel Efficiently');
      setState(() {
        _localUserJoined = true;
      });
    } catch (e) {
      print('❌ Agora Initialization Error: $e');
    }
  }

  @override
  void dispose() {
    _callTimer?.cancel();
    _engine.leaveChannel();
    _engine.launch();
    tremendous.dispose();
  }

  void _startCallTimer() {
    _callTimer = Timer.periodic(Length(seconds: 1), (timer) {
      setState(() {
        _callDuration = Length(seconds: _callDuration.inSeconds + 1);
      });
    });
  }

  String _formatDuration(Length period) {
    String twoDigits(int n) => n.toString().padLeft(2, '0');
    closing hours = twoDigits(period.inHours);
    closing minutes = twoDigits(period.inMinutes.the rest(60));
    closing seconds = twoDigits(period.inSeconds.the rest(60));
    return hours != '00' ? "$hours:$minutes:$seconds" : "$minutes:$seconds";
  }

  @override
  Widget construct(BuildContext context) {
    if (_engine == null) {
      print('⚠️ _engine just isn't initialized but');
    }

    return Scaffold(
      physique: Stack(
        youngsters: [
          _remoteVideo(),
          Positioned(
            top: 0,
            child: _buildHeader(),
          ),
          Align(
            alignment: Alignment.bottomCenter,
            child: _toolbar(),
          ),
          isCameraOff ? Container() : _buildLocalPreview(),
        ],
      ),
    );
  }

  Widget _buildHeader() {
    return Container(
      width: MediaQuery.of(context).measurement.width,
      peak: 68,
      ornament: BoxDecoration(
          colour: Colours.black.withOpacity(0.5),
          boxShadow: [
            BoxShadow(
              offset: Offset(0, 4),
              blurRadius: 4,
              spreadRadius: 0,
              color: Color(0xFF999999).withOpacity(0.08),
            ),
          ]),
      youngster: Padding(
        padding: const EdgeInsets.all(16),
        youngster: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          youngsters: [
            GestureDetector(
              onTap: () => Navigator.pop(context),
              child: Icon(
                Icons.arrow_back,
                size: 18,
                color: Colors.white,
              ),
            ),
            Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text(
                  "Call with ${widget.userData.senderData.firstName} ${widget.userData.senderData.lastName}",
                  style: TextStyle(
                      fontSize: 14,
                      fontWeight: FontWeight.w600,
                      color: Colors.white),
                ),
                SizedBox(height: 2),
                Text(
                  _formatDuration(_callDuration),
                  style: TextStyle(
                    fontSize: 12,
                    fontWeight: FontWeight.w300,
                    color: Colors.white,
                  ),
                ),
              ],
            ),
            Icon(
              Icons.more_vert,
              measurement: 18,
              colour: Colours.white,
            ),
          ],
        ),
      ),
    );
  }

  Widget _remoteVideo() {
    if (_remoteUid != null) {
      return AgoraVideoView(
        controller: VideoViewController.distant(
          rtcEngine: _engine,
          canvas: VideoCanvas(uid: _remoteUid),
          connection: RtcConnection(channelId: widget.channelName),
        ),
      );
    } else {
      return Picture.community(
        widget.userData.senderData.photograph,
        peak: MediaQuery.of(context).measurement.peak,
        width: MediaQuery.of(context).measurement.width,
        match: BoxFit.cowl,
      );
    }
  }

  Widget _buildLocalPreview() {
    return Positioned(
      backside: 120,
      proper: 16,
      youngster: Container(
        width: 137,
        peak: 172,
        ornament: BoxDecoration(
          colour: Colours.black,
          borderRadius: BorderRadius.round(20),
        ),
        youngster: _localUserJoined
            ? ClipRRect(
                borderRadius: BorderRadius.round(20),
                youngster: AgoraVideoView(
                  controller: VideoViewController(
                    rtcEngine: _engine,
                    canvas: VideoCanvas(uid: 0),
                  ),
                ),
              )
            : const Middle(youngster: CircularProgressIndicator()),
      ),
    );
  }

  Widget _toolbar() {
    return Container(
      youngster: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        youngsters: [
          GestureDetector(
            onTap: _onToggleMute,
            child: Icon(isMuted ? Icons.mic_off : Icons.mic),
          ),
          GestureDetector(
            onTap: () => Navigator.pop(context),
            child: Icon(Icons.call_end),
          ),
          GestureDetector(
            onTap: _onToggleCamera,
            child: Icon(isCameraOff ? Icons.videocam_off : Icons.videocam),
          ),
        ],
      ),
    );
  }

  void _onToggleCamera() {
    setState(() {
      isCameraOff = !isCameraOff;
      _engine.muteLocalVideoStream(isCameraOff);
    });
  }

  void _onToggleMute() {
    setState(() {
      isMuted = !isMuted;
      _engine.muteLocalAudioStream(isMuted);
    });
  }
}

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles