mmoo_live_room

接入

flutter main.dart

  1. init emclient
  2. prociders add ProviderLiveConfig.prividers
  3. localizationsDelegates add Lives.S.delegate
  4. route add PageLiveRoot

安卓添加相册 相机 麦克风权限

安卓工程

andorid-> add video-capture settings.gradle add

include ':app','video-capture'

ios podfile 工程添加


 post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)
    target.build_configurations.each do |config|
      # Here are some configurations automatically generated by flutter

      # You can enable the permissions needed here. For example to enable camera
      # permission, just remove the `#` character in front so it looks like this:

      # ## dart: PermissionGroup.camera
      # 'PERMISSION_CAMERA=1'
      #  Preprocessor definitions can be found in: https://github.com/Baseflow/flutter-permission-handler/blob/master/permission_handler/ios/Classes/PermissionHandlerEnums.h
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',

        ## dart: PermissionGroup.calendar
        # 'PERMISSION_EVENTS=1',

        ## dart: PermissionGroup.reminders
        # 'PERMISSION_REMINDERS=1',

        ## dart: PermissionGroup.contacts
        # 'PERMISSION_CONTACTS=1',

        # dart: PermissionGroup.camera
        'PERMISSION_CAMERA=1',

        # dart: PermissionGroup.microphone
        'PERMISSION_MICROPHONE=1',

        ## dart: PermissionGroup.speech
        # 'PERMISSION_SPEECH_RECOGNIZER=1',

        # dart: PermissionGroup.photos
        'PERMISSION_PHOTOS=1',

        ## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
        # 'PERMISSION_LOCATION=1',

        # dart: PermissionGroup.notification
        'PERMISSION_NOTIFICATIONS=1',

        ## dart: PermissionGroup.mediaLibrary
        # 'PERMISSION_MEDIA_LIBRARY=1',

        ## dart: PermissionGroup.sensors
        # 'PERMISSION_SENSORS=1',

        ## dart: PermissionGroup.bluetooth
        # 'PERMISSION_BLUETOOTH=1',

        ## dart: PermissionGroup.appTrackingTransparency
        # 'PERMISSION_APP_TRACKING_TRANSPARENCY=1',

        ## dart: PermissionGroup.criticalAlerts
        # 'PERMISSION_CRITICAL_ALERTS=1'
      ]

    end
  end
end

关于启动后台配置

wiki 管理后台 配置说明 需要配置 LiveOpenType

关于接听通话,未读消息更新及更新 money

1.接听通话

需要先退出直播间 之后再进入接听电话逻辑

await ConfigLiveGlobalkey.liveRtcKey.currentState
?.userExitRoom();

2.未读消息

在进入 live 模块 给一个 GlobalKey

void onUnReadCount() async {
try {
int? unread =
await EMClient.getInstance.chatManager.getUnreadMessageCount();
liveRootKey.currentState?.updataUnReadMessags(unread ?? 0);
} catch (e) {}
}

3.更新 money

在进入 live 模块 接收RechargeEvent

  subscription = eventBusBig.on<RechargeEvent>().listen((event) {
    liveRootKey.currentState
        ?.updataUserInfo(money: int.parse(event.money ?? '0'));
  });

4.关于 LiveMethonDelegate

(1). showLiveReportPage 打开举报页面

(2). openIMMessageListPage 打开消息列表

(3). showRechargeblePage 打开充值页面

(4). showLiveIMChatPage(String userId) 打开充值页面

(5). showLiveCallVideoPage(String userId) 开始播放视频通话

(6). blackUserMoney(String money) 向外更新 money 余额

(7). setImSocketMessageHandler(LiveSocketEventHandler handler) 设置环信 imhandler 设置了之后 直播间才有 im 链接能力 在环信onMessagesReceived回调中

 @override
void onMessagesReceived(List<EMMessage> messages) {
  if (_liveSocketEventHandler != null) {
    messages
        .where((element) => element.chatType == EMMessageChatType.ChatRoom)
        .toList()
        .forEach((element) {
      _liveSocketEventHandler?.onMessageReceived(element);
    });
  }
  List<EMMessage> chatMessages = messages
      .where((element) => element.chatType != EMMessageChatType.ChatRoom)
      .toList();
  if (chatMessages.isNotEmpty) {
    imPluginDelegateList.forEach((element) {
      element.onMessageReceived(messages);
    });
    // _onImLivePluginDelegate?.onMessageReceived(messages);
  }
}

在环信onCmdMessagesReceived回调中

if (_liveSocketEventHandler != null) {
messages
.where((element) {
if (element.body is EMCmdMessageBody) {
EMCmdMessageBody cmdMessageBody =
element.body as EMCmdMessageBody;
if (cmdMessageBody.action == 'live') {
return true;
}
}
return false;
})
.toList()
.forEach((element) {
_liveSocketEventHandler?.onMessageReceived(element);
});
}

(8). setOnConnection(OnImLivePluginDelegate delegate) 设置 im 在线状态回调

  1. pubspec.yaml 添加
mmoo_live_room:
  git:
    url: https://gitee.com/mimo_1/mmoo-live-room.git
    ref: <最新版>
  1. 修改 mmoo_base_video 里面的 美颜版本

  2. LoneMainPageLy 添加直播列表 tabbar

  3. MainDao.initConfig 添加 LiveOpenType BEKEY

  4. LoneVideoUtilLy 添加直播代码 详见代码


 @override
 void onMessagesReceived(List<EMMessage> messages) {
   if (_liveSocketEventHandler != null) {
     messages
         .where((element) => element.chatType == EMMessageChatType.ChatRoom)
         .toList()
         .forEach((element) {
       _liveSocketEventHandler?.onMessageReceived(element);
     });
   }
   List<EMMessage> chatMessages = messages
       .where((element) => element.chatType != EMMessageChatType.ChatRoom)
       .toList();
   if (chatMessages.isNotEmpty) {
     imPluginDelegateList.forEach((element) {
       element.onLoneMessageReceivedLy(messages);
     });
   }
 }

 @override
 void onCmdMessagesReceived(List<EMMessage> messages) {
   AppConfig.printLog('onCmdMessagesReceived');
   if (_liveSocketEventHandler != null) {
     messages
         .where((element) {
           if (element.body is EMCmdMessageBody) {
             EMCmdMessageBody cmdMessageBody =
                 element.body as EMCmdMessageBody;
             if (cmdMessageBody.action == 'live') {
               return true;
             }
           }
           return false;
         })
         .toList()
         .forEach((element) {
           _liveSocketEventHandler?.onMessageReceived(element);
         });
   }
   return super.onCmdMessagesReceived(messages);
 }
  1. requestLoneVideoPermissionLy 函数 添加
await ConfigLiveGlobalkey.liveRtcKey.currentState?.userExitRoom();
CommonUtils.dismiss();
  1. 在欢迎页添加
Future initialization() async {
   CommonUtils.toast = ((msg) {
     LoneCommonUtilLy.showErrorToastLy(LoneRouterLy.context, res: msg);
   });
   CommonUtils.toastDismiss = (() {
     if (RechargeUtils.instance.showLoading == true) {
       Navigator.pop(context);
     }
   });
   CommonUtils.toastLoad = ((status) {
     if (RechargeUtils.instance.showLoading == false) {
       LoneCommonUtilLy.showLoneLoadingDialogLy(context, text: status);
     }
   });
 }
  1. 添加充值成功回调 然后更新
liveRootKey.currentState?.updataUserInfo(money: int.parse((event.money ?? '0'))); ventBusLone.on<LoneRechargeEventLy>().listen((event)
  1. main.dart 添加 prividers.addAll(ProviderLiveConfig.prividers); 及 LiveS.S.delegate,

  2. 添加在直播间内接收到通话邀请的提示 onLoneReceivedByPeerLy 添加样式判断

  3. goUserPage 添加 goLivePage

  4. 会话列表 处理一下只展示单聊会话 updateConversationList

list.removeWhere((element) => element.type != EMConversationType.Chat);
  1. 直播间接收到通话邀请
void onReceivedByPeer(context) {
    rtmClient?.onRemoteInvitationReceivedByPeer =
        (AgoraRtmRemoteInvitation invite) async {
      try {
        if ((!VideoChatPage.sOpen || VideoChatPage.sOpenPop) &&
            !RechargeUtils.instance.showLoading) {
          var message = CallEntity.fromJson(jsonDecode(invite.content!));
          AnchorEntity anchorEntity =
              AnchorEntity.call(message.userName, message.userImage);
          if (PageLiveRoot.inLivePage) {
            if (_invite != null) {
              _timer?.cancel();
              _supportEntry?.dismiss();
              _supportEntry = null;
              _invite = null;
              await rtmClient
                  ?.refuseRemoteInvitation({'callerId': _invite?.callerId});
            }
            _invite = invite;
            _supportEntry?.dismiss();
            _supportEntry = showOverlayNotification((entryContext1) {
              return BigLiveVideoInvitationWidget().showOverlayNotificationMessage(
                  anchorEntity, onPick: () async {
                _supportEntry?.dismiss();
                _supportEntry = null;
                Future.delayed(Duration(milliseconds: 200), () {
                  requestVideoPermission(context,
                      userId: invite.callerId,
                      call: false,
                      callId: message.callId,
                      channelId: invite.channelId,
                      dial: false,
                      anchorEntity: anchorEntity,
                      invite: invite);
                });
              }, onhangup: () {
                _timer?.cancel();
                _supportEntry?.dismiss();
                _supportEntry = null;
                _invite = null;
                rtmClient
                    ?.refuseRemoteInvitation({'callerId': invite.callerId});
              });
            }, duration: Duration(seconds: 50));
            _timer = Timer.periodic(Duration(seconds: AppConfig), (timer) {
              _timer?.cancel();
              if (_supportEntry != null) {
                _invite = null;
                rtmClient
                    ?.refuseRemoteInvitation({'callerId': invite.callerId});
              }
            });
          } else {
            requestVideoPermission(context,
                userId: invite.callerId,
                call: false,
                callId: message.callId,
                channelId: invite.channelId,
                dial: false,
                anchorEntity: anchorEntity,
                invite: invite);
          }
        } else {
          rtmClient?.refuseRemoteInvitation({'callerId': invite.callerId});
        }
      } catch (e) {
        AppConfig.printLog(e);
      }
    };
    rtmClient?.onRemoteInvitationCanceled =
        (AgoraRtmRemoteInvitation invite) async {
      _timer?.cancel();
      if (_supportEntry != null) {
        _invite = null;
        rtmClient?.refuseRemoteInvitation({'callerId': invite.callerId});
      }
    };
  }
  1. 未读消息更新

从聊天列表或者聊天页返回添加 eventBusLone.fire(LoneHomeUnReadEventLy());

    subscriptionUn =
        eventBusLone.on<LoneHomeUnReadEventLy>().listen((event) async {
      onUnReadCount();
    });
    void onUnReadCount() async {
    try {
      int? unread =
          await EMClient.getInstance.chatManager.getUnreadMessageCount();
      liveRootKey.currentState?.updataUnReadMessags(unread ?? 0);
    } catch (e) {}
  }

flutter packages pub publish --server=https://pub.dartlang.org

export http_proxy=http://127.0.0.1:58591; export https_proxy=http://127.0.0.1:58591;

Libraries

config_live_app
config_live_globalkey
config_live_methon
config_live_socket
config_live_typedef
json_convert_content
json_field
l10n
live_socket_event_handler
manager_live
messages_all
messages_de
messages_en
messages_es
messages_fr
messages_it
messages_ja
mmoo_live_room
model_lastLive_entity
model_lastLive_entity.g
model_live_care_user_list_entity
model_live_care_user_list_entity.g
model_live_gift_list_entity
model_live_gift_list_entity.g
model_live_headFrame_entity
model_live_headFrame_entity.g
model_live_info_entity
model_live_info_entity.g
model_live_list_info_entity
model_live_list_info_entity.g
model_live_send_gift_entity
model_live_send_gift_entity.g
model_live_user_info
model_live_user_info_entity
model_live_user_info_entity.g
model_live_user_list_entity
model_live_user_list_entity.g
model_rtm_message
overlay_drag_live
page_beginlive_live
page_beginlive_peoples
page_beginlive_single
page_beginlive_voice
page_live_chatlist
page_live_memberlist
page_live_root
page_live_rtc
page_live_streamer
provider_live_chat_messages
provider_live_config
provider_live_header_user
provider_live_im_unread
provider_live_info_entity
provider_live_join_place
provider_live_online
provider_live_placelist_info
provider_live_user
utils_engine_manager
utils_live
utils_live_alert
utils_live_colors
utils_live_dlog
utils_live_image
utils_live_permission
utils_live_repeat_click
utils_live_svga_widget
utils_live_textStyle
widget_action_btns
widget_begin_live_videoinfo
widget_beginlive_face
widget_live_alert
widget_live_apply_list
widget_live_begin_join
widget_live_black_list
widget_live_chat_messages
widget_live_chatlist
widget_live_flollow_list
widget_live_gift_show
widget_live_giftlist
widget_live_guest_list
widget_live_header_list
widget_live_incomeState
widget_live_input
widget_live_input_white
widget_live_invite_placelist
widget_live_join_type
widget_live_language
widget_live_liveheader
widget_live_master_operation
widget_live_memberlist
widget_live_more
widget_live_more_choose
widget_live_place_volume
widget_live_private
widget_live_ride_show
widget_live_room_announcement
widget_live_room_info
widget_live_setting
widget_live_stream_multi_video
widget_live_stream_single_video
widget_live_stream_voice_sounds
widget_live_stream_voice_video
widget_live_svga_show
widget_live_user_info
widget_live_user_wait_list
widget_open_header
widget_owner_manager
widget_round_under_linetab
widget_user_info
widght_live_bottom_btn
wild_fire_chat_callbacks