Commit 603302ca authored by Alex朱枝文's avatar Alex朱枝文

接入声网SDK以及直播间搭建

parent 23987683
...@@ -107,7 +107,8 @@ target 'galaxy' do ...@@ -107,7 +107,8 @@ target 'galaxy' do
pod 'QY_iOS_SDK', '9.9.2' pod 'QY_iOS_SDK', '9.9.2'
#阿里云日志 #阿里云日志
pod 'AliyunLogProducer', '4.3.3' pod 'AliyunLogProducer', '4.3.3'
#声网SDK播放器等(先弄完整的,后续剪裁)
pod 'AgoraRtcEngine_iOS', '4.4.0' #, :subspecs => ['RtcBasic']
end end
......
...@@ -284,6 +284,14 @@ ...@@ -284,6 +284,14 @@
044F396B2CBA7D3F007CA277 /* YHHKVisaRenewalPaymentViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 044F396A2CBA7D3F007CA277 /* YHHKVisaRenewalPaymentViewModel.swift */; }; 044F396B2CBA7D3F007CA277 /* YHHKVisaRenewalPaymentViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 044F396A2CBA7D3F007CA277 /* YHHKVisaRenewalPaymentViewModel.swift */; };
044F396D2CBA7FD1007CA277 /* YHHKVisaRenewalPaymentList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 044F396C2CBA7FD1007CA277 /* YHHKVisaRenewalPaymentList.swift */; }; 044F396D2CBA7FD1007CA277 /* YHHKVisaRenewalPaymentList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 044F396C2CBA7FD1007CA277 /* YHHKVisaRenewalPaymentList.swift */; };
04506F552C6F57E600738EA1 /* YHFamilyMemberInfoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04506F542C6F57E600738EA1 /* YHFamilyMemberInfoCell.swift */; }; 04506F552C6F57E600738EA1 /* YHFamilyMemberInfoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04506F542C6F57E600738EA1 /* YHFamilyMemberInfoCell.swift */; };
04564D452CF3812F004456E4 /* YHMediaProtocolUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04564D442CF3812F004456E4 /* YHMediaProtocolUtils.swift */; };
04564D472CF3851D004456E4 /* YHPlayerControlView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04564D462CF3851D004456E4 /* YHPlayerControlView.swift */; };
04564D492CF385D9004456E4 /* YHBasePlayerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04564D482CF385D9004456E4 /* YHBasePlayerViewController.swift */; };
04564D4B2CF389DD004456E4 /* YHLivePlayerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04564D4A2CF389DD004456E4 /* YHLivePlayerViewController.swift */; };
04564D4D2CF38D16004456E4 /* YHLiveMessageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04564D4C2CF38D16004456E4 /* YHLiveMessageCell.swift */; };
04564D4F2CF38E20004456E4 /* YHLiveMessageListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04564D4E2CF38E20004456E4 /* YHLiveMessageListView.swift */; };
04564D512CF38EA4004456E4 /* YHMessageInputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04564D502CF38EA4004456E4 /* YHMessageInputView.swift */; };
04564D532CF38FE2004456E4 /* YHVODPlayerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04564D522CF38FE2004456E4 /* YHVODPlayerViewController.swift */; };
0457920B2CBCE7B200EBD99B /* YHResignUploadTravelCardViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0457920A2CBCE7B200EBD99B /* YHResignUploadTravelCardViewModel.swift */; }; 0457920B2CBCE7B200EBD99B /* YHResignUploadTravelCardViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0457920A2CBCE7B200EBD99B /* YHResignUploadTravelCardViewModel.swift */; };
0457920D2CBCE8A800EBD99B /* YHResignUploadTravelCardListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0457920C2CBCE8A800EBD99B /* YHResignUploadTravelCardListModel.swift */; }; 0457920D2CBCE8A800EBD99B /* YHResignUploadTravelCardListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0457920C2CBCE8A800EBD99B /* YHResignUploadTravelCardListModel.swift */; };
0457920F2CBCE9D000EBD99B /* YHResignUploadTravelCardListTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0457920E2CBCE9D000EBD99B /* YHResignUploadTravelCardListTableViewCell.swift */; }; 0457920F2CBCE9D000EBD99B /* YHResignUploadTravelCardListTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0457920E2CBCE9D000EBD99B /* YHResignUploadTravelCardListTableViewCell.swift */; };
...@@ -1319,6 +1327,14 @@ ...@@ -1319,6 +1327,14 @@
044F396A2CBA7D3F007CA277 /* YHHKVisaRenewalPaymentViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHHKVisaRenewalPaymentViewModel.swift; sourceTree = "<group>"; }; 044F396A2CBA7D3F007CA277 /* YHHKVisaRenewalPaymentViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHHKVisaRenewalPaymentViewModel.swift; sourceTree = "<group>"; };
044F396C2CBA7FD1007CA277 /* YHHKVisaRenewalPaymentList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHHKVisaRenewalPaymentList.swift; sourceTree = "<group>"; }; 044F396C2CBA7FD1007CA277 /* YHHKVisaRenewalPaymentList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHHKVisaRenewalPaymentList.swift; sourceTree = "<group>"; };
04506F542C6F57E600738EA1 /* YHFamilyMemberInfoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHFamilyMemberInfoCell.swift; sourceTree = "<group>"; }; 04506F542C6F57E600738EA1 /* YHFamilyMemberInfoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHFamilyMemberInfoCell.swift; sourceTree = "<group>"; };
04564D442CF3812F004456E4 /* YHMediaProtocolUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHMediaProtocolUtils.swift; sourceTree = "<group>"; };
04564D462CF3851D004456E4 /* YHPlayerControlView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHPlayerControlView.swift; sourceTree = "<group>"; };
04564D482CF385D9004456E4 /* YHBasePlayerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHBasePlayerViewController.swift; sourceTree = "<group>"; };
04564D4A2CF389DD004456E4 /* YHLivePlayerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHLivePlayerViewController.swift; sourceTree = "<group>"; };
04564D4C2CF38D16004456E4 /* YHLiveMessageCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHLiveMessageCell.swift; sourceTree = "<group>"; };
04564D4E2CF38E20004456E4 /* YHLiveMessageListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHLiveMessageListView.swift; sourceTree = "<group>"; };
04564D502CF38EA4004456E4 /* YHMessageInputView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHMessageInputView.swift; sourceTree = "<group>"; };
04564D522CF38FE2004456E4 /* YHVODPlayerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHVODPlayerViewController.swift; sourceTree = "<group>"; };
0457920A2CBCE7B200EBD99B /* YHResignUploadTravelCardViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHResignUploadTravelCardViewModel.swift; sourceTree = "<group>"; }; 0457920A2CBCE7B200EBD99B /* YHResignUploadTravelCardViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHResignUploadTravelCardViewModel.swift; sourceTree = "<group>"; };
0457920C2CBCE8A800EBD99B /* YHResignUploadTravelCardListModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHResignUploadTravelCardListModel.swift; sourceTree = "<group>"; }; 0457920C2CBCE8A800EBD99B /* YHResignUploadTravelCardListModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHResignUploadTravelCardListModel.swift; sourceTree = "<group>"; };
0457920E2CBCE9D000EBD99B /* YHResignUploadTravelCardListTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHResignUploadTravelCardListTableViewCell.swift; sourceTree = "<group>"; }; 0457920E2CBCE9D000EBD99B /* YHResignUploadTravelCardListTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHResignUploadTravelCardListTableViewCell.swift; sourceTree = "<group>"; };
...@@ -2842,6 +2858,52 @@ ...@@ -2842,6 +2858,52 @@
path = VM; path = VM;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
04564D3F2CF1BE76004456E4 /* LivestreamSales(直播销售) */ = {
isa = PBXGroup;
children = (
04564D432CF380D6004456E4 /* M */,
04564D412CF1BEA2004456E4 /* V */,
04564D402CF1BE99004456E4 /* C */,
);
path = "LivestreamSales(直播销售)";
sourceTree = "<group>";
};
04564D402CF1BE99004456E4 /* C */ = {
isa = PBXGroup;
children = (
04564D482CF385D9004456E4 /* YHBasePlayerViewController.swift */,
04564D4A2CF389DD004456E4 /* YHLivePlayerViewController.swift */,
04564D522CF38FE2004456E4 /* YHVODPlayerViewController.swift */,
);
path = C;
sourceTree = "<group>";
};
04564D412CF1BEA2004456E4 /* V */ = {
isa = PBXGroup;
children = (
04564D462CF3851D004456E4 /* YHPlayerControlView.swift */,
04564D4C2CF38D16004456E4 /* YHLiveMessageCell.swift */,
04564D4E2CF38E20004456E4 /* YHLiveMessageListView.swift */,
04564D502CF38EA4004456E4 /* YHMessageInputView.swift */,
);
path = V;
sourceTree = "<group>";
};
04564D432CF380D6004456E4 /* M */ = {
isa = PBXGroup;
children = (
04564D442CF3812F004456E4 /* YHMediaProtocolUtils.swift */,
);
path = M;
sourceTree = "<group>";
};
04564D542CF413A1004456E4 /* IM(环信) */ = {
isa = PBXGroup;
children = (
);
path = "IM(环信)";
sourceTree = "<group>";
};
045EED972B9F171A0022A143 /* ServiceProcess(我的信息流程) */ = { 045EED972B9F171A0022A143 /* ServiceProcess(我的信息流程) */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
...@@ -5176,6 +5238,7 @@ ...@@ -5176,6 +5238,7 @@
A5ACE91B2B4564F7002C94D2 /* Modules */ = { A5ACE91B2B4564F7002C94D2 /* Modules */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
04564D542CF413A1004456E4 /* IM(环信) */,
04129E842CD0C8000072F87B /* AliYunLog(阿里云日志) */, 04129E842CD0C8000072F87B /* AliYunLog(阿里云日志) */,
041470892C885EC900B7B688 /* ButlerServiceManager(银河管家) */, 041470892C885EC900B7B688 /* ButlerServiceManager(银河管家) */,
A596CADD2C6B9AF200F85797 /* HomeAlertViewManager(首页弹窗管理) */, A596CADD2C6B9AF200F85797 /* HomeAlertViewManager(首页弹窗管理) */,
...@@ -5191,6 +5254,7 @@ ...@@ -5191,6 +5254,7 @@
A5ACE8D82B4564F7002C94D2 /* Login(登录) */, A5ACE8D82B4564F7002C94D2 /* Login(登录) */,
A5ACE9162B4564F7002C94D2 /* IntelligentService(服务中心) */, A5ACE9162B4564F7002C94D2 /* IntelligentService(服务中心) */,
A5ACE8E72B4564F7002C94D2 /* Mine(我的) */, A5ACE8E72B4564F7002C94D2 /* Mine(我的) */,
04564D3F2CF1BE76004456E4 /* LivestreamSales(直播销售) */,
); );
path = Modules; path = Modules;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -6013,6 +6077,7 @@ ...@@ -6013,6 +6077,7 @@
A5FD63C92B63A35B00D1D9DA /* YHInformationFillTipsAlertView.swift in Sources */, A5FD63C92B63A35B00D1D9DA /* YHInformationFillTipsAlertView.swift in Sources */,
04174D762BCD5B74000BA46D /* YHMsgListModel.swift in Sources */, 04174D762BCD5B74000BA46D /* YHMsgListModel.swift in Sources */,
045EEEE32B9F171A0022A143 /* YHMySignatureListModel.swift in Sources */, 045EEEE32B9F171A0022A143 /* YHMySignatureListModel.swift in Sources */,
04564D452CF3812F004456E4 /* YHMediaProtocolUtils.swift in Sources */,
04FB01D22C23FCDD0040115D /* YHMatchCardUsageGuideView.swift in Sources */, 04FB01D22C23FCDD0040115D /* YHMatchCardUsageGuideView.swift in Sources */,
A5EB6C702C69FB9A0081FB6C /* YHOfficialApprovalResultVC.swift in Sources */, A5EB6C702C69FB9A0081FB6C /* YHOfficialApprovalResultVC.swift in Sources */,
049AC4C62BC3E55300F857F4 /* YHServiceSectionView.swift in Sources */, 049AC4C62BC3E55300F857F4 /* YHServiceSectionView.swift in Sources */,
...@@ -6040,6 +6105,7 @@ ...@@ -6040,6 +6105,7 @@
04CA2C032CB7D3C200F36DE7 /* YHFileExplainReasonInputView.swift in Sources */, 04CA2C032CB7D3C200F36DE7 /* YHFileExplainReasonInputView.swift in Sources */,
04213B292C48EF5300797900 /* YHHomeInformationViewController.swift in Sources */, 04213B292C48EF5300797900 /* YHHomeInformationViewController.swift in Sources */,
A5DF9C692C78BE6000CE48E6 /* YHUploadCertificateDetailModel.swift in Sources */, A5DF9C692C78BE6000CE48E6 /* YHUploadCertificateDetailModel.swift in Sources */,
04564D4D2CF38D16004456E4 /* YHLiveMessageCell.swift in Sources */,
04F4A52A2CB8D5FA0026D469 /* YHForwardArriveHKAlertView.swift in Sources */, 04F4A52A2CB8D5FA0026D469 /* YHForwardArriveHKAlertView.swift in Sources */,
044EE2442C92F48200A2FE3A /* YHResignCertificateEvisaTableViewCell.swift in Sources */, 044EE2442C92F48200A2FE3A /* YHResignCertificateEvisaTableViewCell.swift in Sources */,
048B2A4D2BC7DAE800A93BF0 /* YHMyLikeViewModel.swift in Sources */, 048B2A4D2BC7DAE800A93BF0 /* YHMyLikeViewModel.swift in Sources */,
...@@ -6092,6 +6158,7 @@ ...@@ -6092,6 +6158,7 @@
0419A09C2C48FBCB00A5FCFA /* YHInvitationWithGiftsHeadView.swift in Sources */, 0419A09C2C48FBCB00A5FCFA /* YHInvitationWithGiftsHeadView.swift in Sources */,
A5ACE9472B4564F7002C94D2 /* YHHUD.swift in Sources */, A5ACE9472B4564F7002C94D2 /* YHHUD.swift in Sources */,
045A08C02C37ABF500BCBABA /* YHSegmentView.swift in Sources */, 045A08C02C37ABF500BCBABA /* YHSegmentView.swift in Sources */,
04564D532CF38FE2004456E4 /* YHVODPlayerViewController.swift in Sources */,
A5ACE9412B4564F7002C94D2 /* Dictionary+Extension.swift in Sources */, A5ACE9412B4564F7002C94D2 /* Dictionary+Extension.swift in Sources */,
047AA3EA2C4A6FB7009C4554 /* YHDetailViewController.swift in Sources */, 047AA3EA2C4A6FB7009C4554 /* YHDetailViewController.swift in Sources */,
045EEE8F2B9F171A0022A143 /* YHPreviewInfoProjectItemView.swift in Sources */, 045EEE8F2B9F171A0022A143 /* YHPreviewInfoProjectItemView.swift in Sources */,
...@@ -6121,12 +6188,14 @@ ...@@ -6121,12 +6188,14 @@
04912F622CB66E6300CC3105 /* YHResignConfirmInfoListViewController.swift in Sources */, 04912F622CB66E6300CC3105 /* YHResignConfirmInfoListViewController.swift in Sources */,
04EFC8E92C903F1100FC680F /* YHResignMaterialViewModel.swift in Sources */, 04EFC8E92C903F1100FC680F /* YHResignMaterialViewModel.swift in Sources */,
04256DE82C7314B500A37BA4 /* YHSelectApplicantCell.swift in Sources */, 04256DE82C7314B500A37BA4 /* YHSelectApplicantCell.swift in Sources */,
04564D4B2CF389DD004456E4 /* YHLivePlayerViewController.swift in Sources */,
045EEE9D2B9F171A0022A143 /* YHWorkItemListViewModel.swift in Sources */, 045EEE9D2B9F171A0022A143 /* YHWorkItemListViewModel.swift in Sources */,
A5ACE9392B4564F7002C94D2 /* UIDevice+Extension.swift in Sources */, A5ACE9392B4564F7002C94D2 /* UIDevice+Extension.swift in Sources */,
0430E66E2C749AAF000511E2 /* YHAdopterResidentViewController.swift in Sources */, 0430E66E2C749AAF000511E2 /* YHAdopterResidentViewController.swift in Sources */,
04F2434F2C9BB74E00DF2C74 /* YHHKRecordsOccupyingSpaceCell.swift in Sources */, 04F2434F2C9BB74E00DF2C74 /* YHHKRecordsOccupyingSpaceCell.swift in Sources */,
04CE1AD02C2AD91F001CB80A /* YHActivityListModel.swift in Sources */, 04CE1AD02C2AD91F001CB80A /* YHActivityListModel.swift in Sources */,
0430E66C2C749573000511E2 /* YHAdopterCardExplainTableViewCell.swift in Sources */, 0430E66C2C749573000511E2 /* YHAdopterCardExplainTableViewCell.swift in Sources */,
04564D492CF385D9004456E4 /* YHBasePlayerViewController.swift in Sources */,
045EEEE82B9F171A0022A143 /* YHFamilyMemberViewModel.swift in Sources */, 045EEEE82B9F171A0022A143 /* YHFamilyMemberViewModel.swift in Sources */,
045EEED02B9F171A0022A143 /* YHScoreResultView.swift in Sources */, 045EEED02B9F171A0022A143 /* YHScoreResultView.swift in Sources */,
044D0BFA2C215C6F00C5CF5E /* YHSettingItem.swift in Sources */, 044D0BFA2C215C6F00C5CF5E /* YHSettingItem.swift in Sources */,
...@@ -6299,6 +6368,7 @@ ...@@ -6299,6 +6368,7 @@
0414BDAB2BC7E9C200225367 /* YHMyPermissionCell.swift in Sources */, 0414BDAB2BC7E9C200225367 /* YHMyPermissionCell.swift in Sources */,
045792152CBD041F00EBD99B /* YHResignUploadTravelHKTableViewCell.swift in Sources */, 045792152CBD041F00EBD99B /* YHResignUploadTravelHKTableViewCell.swift in Sources */,
04C8F4832B7216D800ADF59B /* YHUserInfoHeaderView.swift in Sources */, 04C8F4832B7216D800ADF59B /* YHUserInfoHeaderView.swift in Sources */,
04564D512CF38EA4004456E4 /* YHMessageInputView.swift in Sources */,
045EEEAF2B9F171A0022A143 /* YHWorkExperienceTextItemView.swift in Sources */, 045EEEAF2B9F171A0022A143 /* YHWorkExperienceTextItemView.swift in Sources */,
A5ACE9492B4564F7002C94D2 /* YHHUDSuccessView.swift in Sources */, A5ACE9492B4564F7002C94D2 /* YHHUDSuccessView.swift in Sources */,
04B360EF2C620975001EB053 /* YHPrincipleUploadStatusCell.swift in Sources */, 04B360EF2C620975001EB053 /* YHPrincipleUploadStatusCell.swift in Sources */,
...@@ -6347,6 +6417,7 @@ ...@@ -6347,6 +6417,7 @@
045A08C22C37EB8B00BCBABA /* YHMyFileListNoneCell.swift in Sources */, 045A08C22C37EB8B00BCBABA /* YHMyFileListNoneCell.swift in Sources */,
04F2435F2C9D1C0600DF2C74 /* YHHKRecordsStayingPersonnelCell.swift in Sources */, 04F2435F2C9D1C0600DF2C74 /* YHHKRecordsStayingPersonnelCell.swift in Sources */,
A5EB6C732C69FB9A0081FB6C /* YHOffivialApprovalSuccessCheckView.swift in Sources */, A5EB6C732C69FB9A0081FB6C /* YHOffivialApprovalSuccessCheckView.swift in Sources */,
04564D4F2CF38E20004456E4 /* YHLiveMessageListView.swift in Sources */,
04FD85682C21277800BEF9C5 /* YHMyNameCardAvatarInfoCell.swift in Sources */, 04FD85682C21277800BEF9C5 /* YHMyNameCardAvatarInfoCell.swift in Sources */,
A566A79A2C219FA400980D06 /* YHHomeSalonAreaView.swift in Sources */, A566A79A2C219FA400980D06 /* YHHomeSalonAreaView.swift in Sources */,
04213B312C4917BD00797900 /* YHHomeInfoDetailViewController.swift in Sources */, 04213B312C4917BD00797900 /* YHHomeInfoDetailViewController.swift in Sources */,
...@@ -6357,6 +6428,7 @@ ...@@ -6357,6 +6428,7 @@
A5ACE9382B4564F7002C94D2 /* UIApplication+Extension.swift in Sources */, A5ACE9382B4564F7002C94D2 /* UIApplication+Extension.swift in Sources */,
04B401F22CEB19C1005C61A9 /* YHIncomeRecordCompleteModel.swift in Sources */, 04B401F22CEB19C1005C61A9 /* YHIncomeRecordCompleteModel.swift in Sources */,
0468D42B2B55019900CFB916 /* YHAnalytics.swift in Sources */, 0468D42B2B55019900CFB916 /* YHAnalytics.swift in Sources */,
04564D472CF3851D004456E4 /* YHPlayerControlView.swift in Sources */,
04912F842CB7D14D00CC3105 /* YHResignScheduleLineCollectCell.swift in Sources */, 04912F842CB7D14D00CC3105 /* YHResignScheduleLineCollectCell.swift in Sources */,
0445E6B12BE9E15C003C52F9 /* YHFindAppNewVersionView.swift in Sources */, 0445E6B12BE9E15C003C52F9 /* YHFindAppNewVersionView.swift in Sources */,
045EEEBE2B9F171A0022A143 /* YHResultBottomView.swift in Sources */, 045EEEBE2B9F171A0022A143 /* YHResultBottomView.swift in Sources */,
......
//
// YHBasePlayerViewController.swift
// galaxy
//
// Created by alexzzw on 2024/11/25.
// Copyright © 2024 https://www.galaxy-immi.com. All rights reserved.
//
import AgoraRtcKit
import UIKit
class YHBasePlayerViewController: UIViewController {
// MARK: - Properties
var playerKit: AgoraRtcMediaPlayerProtocol!
var agoraKit: AgoraRtcEngineKit!
// MARK: - UI Components
private lazy var containerView: UIView = {
let view = UIView()
view.backgroundColor = .black
return view
}()
lazy var playerView: UIView = {
let view = UIView()
view.backgroundColor = .black
return view
}()
private lazy var controlView: YHPlayerControlView = {
let view = YHPlayerControlView()
view.delegate = self
return view
}()
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
setupAgoraKit()
}
// MARK: - Setup
private func setupUI() {
view.backgroundColor = .black
view.addSubview(containerView)
containerView.addSubview(playerView)
containerView.addSubview(controlView)
setupConstraints()
}
private func setupConstraints() {
containerView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
playerView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
controlView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
}
private func setupAgoraKit() {
let config = AgoraRtcEngineConfig()
config.appId = YhConstant.AgoraRtcKit.appId
agoraKit = AgoraRtcEngineKit.sharedEngine(with: config, delegate: self)
playerKit = agoraKit.createMediaPlayer(with: self)
playerKit.setView(playerView)
playerKit.setRenderMode(.fit)
}
}
extension YHBasePlayerViewController: YHMediaPlayerViewDelegate {
// MARK: - MediaPlayerViewDelegate
func didTapPlayButton() {
if playerKit.getPlayerState() == .playing {
playerKit.pause()
} else {
playerKit.play()
}
}
func didTapStopButton() {
playerKit.stop()
}
func didSeekToPosition(_ position: Float) {
let duration = playerKit.getDuration()
let seekPosition = Int64(Float(duration) * position)
playerKit.seek(toPosition: Int(seekPosition))
}
func didChangeQuality(_ quality: YHVideoQuality) {
// 根据不同清晰度切换播放源
switch quality {
case .auto:
// 自动码率逻辑
break
case .sd:
// 切换到标清源
break
case .hd:
// 切换到高清源
break
case .fhd:
// 切换到超清源
break
}
}
func didToggleFullscreen() {
// 切换全屏
if UIDevice.current.orientation.isPortrait {
let value = UIInterfaceOrientation.landscapeRight.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
} else {
let value = UIInterfaceOrientation.portrait.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
}
}
}
extension YHBasePlayerViewController: AgoraRtcMediaPlayerDelegate {
// MARK: - AgoraRtcMediaPlayerDelegate
func AgoraRtcMediaPlayer(_ playerKit: AgoraRtcMediaPlayerProtocol,
didChangedTo state: AgoraMediaPlayerState,
reason: AgoraMediaPlayerReason) {
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
switch state {
case .opening:
print("正在打开媒体源")
case .playing:
self.controlView.updatePlayButton(isPlaying: true)
print("正在播放")
case .paused:
self.controlView.updatePlayButton(isPlaying: false)
print("已暂停")
case .stopped:
self.controlView.updatePlayButton(isPlaying: false)
print("已停止")
case .failed:
print("播放失败,错误原因:\(reason.rawValue)")
self.showAlert(message: "播放失败,错误原因:\(reason.rawValue)")
default:
break
}
}
}
func AgoraRtcMediaPlayer(_ playerKit: AgoraRtcMediaPlayerProtocol,
didChangedTo position: Int) {
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
let duration = self.playerKit.getDuration()
guard duration > 0 else { return }
let progress = Float(position) / Float(duration)
let currentTime = self.formatTime(position)
let totalTime = self.formatTime(duration)
self.controlView.updateProgress(progress,
currentTime: currentTime,
totalTime: totalTime)
}
}
}
extension YHBasePlayerViewController: AgoraRtcEngineDelegate {
// MARK: - AgoraRtcEngineDelegate
func rtcEngine(_ engine: AgoraRtcEngineKit, didOccurWarning warningCode: AgoraWarningCode) {
print("Warning: \(warningCode.rawValue)")
}
func rtcEngine(_ engine: AgoraRtcEngineKit, didOccurError errorCode: AgoraErrorCode) {
DispatchQueue.main.async { [weak self] in
self?.showAlert(message: "RTC错误:\(errorCode.rawValue)")
}
}
}
extension YHBasePlayerViewController {
// MARK: - Helper Methods
private func formatTime(_ timeInMilliseconds: Int) -> String {
let totalSeconds = timeInMilliseconds / 1000
let minutes = totalSeconds / 60
let seconds = totalSeconds % 60
return String(format: "%02d:%02d", minutes, seconds)
}
private func showAlert(message: String) {
let alert = UIAlertController(title: "提示",
message: message,
preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "确定", style: .default))
present(alert, animated: true)
}
}
//
// YHLivePlayerViewController.swift
// galaxy
//
// Created by alexzzw on 2024/11/25.
// Copyright © 2024 https://www.galaxy-immi.com. All rights reserved.
//
import AgoraRtcKit
import UIKit
class YHLivePlayerViewController: YHBasePlayerViewController {
// MARK: - Properties
private var roomInfo: YHLiveRoomInfo
private var messageListView: YHLiveMessageListView!
// MARK: - Initialization
init(roomInfo: YHLiveRoomInfo) {
self.roomInfo = roomInfo
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
setupMessageList()
startLive()
}
// MARK: - Setup
private func setupMessageList() {
messageListView = YHLiveMessageListView()
view.addSubview(messageListView)
messageListView.snp.makeConstraints { make in
make.left.right.equalToSuperview()
make.bottom.equalTo(view.safeAreaLayoutGuide)
make.height.equalTo(view.snp.height).multipliedBy(0.3)
}
}
private func startLive() {
play(with: roomInfo.streamUrl)
}
// MARK: - Player Control
private func play(with url: String) {
let mediaSource = AgoraMediaSource()
mediaSource.url = url
mediaSource.autoPlay = true
let result = playerKit.open(with: mediaSource)
if result != 0 {
//showAlert(message: "播放失败,错误码:\(result)")
}
}
}
extension YHLivePlayerViewController {
override func AgoraRtcMediaPlayer(_ playerKit: AgoraRtcMediaPlayerProtocol,
didChangedTo state: AgoraMediaPlayerState,
reason: AgoraMediaPlayerReason) {
super.AgoraRtcMediaPlayer(playerKit, didChangedTo: state, reason: reason)
// 添加直播特定的状态处理
switch state {
case .playing:
// 直播开始时的特殊处理
break
case .stopped:
// 直播结束时的特殊处理
break
default:
break
}
}
}
//
// YHVODPlayerViewController.swift
// galaxy
//
// Created by alexzzw on 2024/11/25.
// Copyright © 2024 https://www.galaxy-immi.com. All rights reserved.
//
import AgoraRtcKit
import UIKit
class YHVODPlayerViewController: YHBasePlayerViewController {
private let videoInfo: YHVideoInfo
private var playConfig: YHVideoPlayConfig
init(videoInfo: YHVideoInfo, playConfig: YHVideoPlayConfig = YHVideoPlayConfig()) {
self.videoInfo = videoInfo
self.playConfig = playConfig
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
setupVideoInfo()
startPlayback()
}
private func setupVideoInfo() {
// 设置视频标题
title = videoInfo.title
// 设置作者信息
setupAuthorInfo()
// 设置播放器配置
setupPlayerConfig()
}
private func setupAuthorInfo() {
// 添加作者信息视图
let authorInfoView = YHVideoAuthorInfoView(author: videoInfo.author)
view.addSubview(authorInfoView)
authorInfoView.snp.makeConstraints { make in
make.top.equalTo(playerView.snp.bottom)
make.left.right.equalToSuperview()
make.height.equalTo(60)
}
}
private func setupPlayerConfig() {
// 设置播放器配置
if playConfig.muteOnStart {
playerKit.adjustPlayoutVolume(0)
}
}
private func startPlayback() {
// 获取合适的视频URL
let networkType: YHNetworkType = getNetworkType()
if let videoUrl = videoInfo.getBestQualityUrl(for: networkType) {
play(with: videoUrl)
} else {
//showAlert(message: "无法获取视频地址")
}
}
private func getNetworkType() -> YHNetworkType {
// 实现网络类型检测逻辑
return .wifi
}
// MARK: - Player Control
private func play(with url: String) {
let mediaSource = AgoraMediaSource()
mediaSource.url = url
mediaSource.autoPlay = true
let result = playerKit.open(with: mediaSource)
if result != 0 {
//showAlert(message: "播放失败,错误码:\(result)")
}
}
private func updatePlayCount() {
// 更新播放次数的逻辑
}
}
// 作者信息视图
class YHVideoAuthorInfoView: UIView {
private let author: YHVideoAuthor
private lazy var avatarImageView: UIImageView = {
let imageView = UIImageView()
imageView.layer.cornerRadius = 20
imageView.layer.masksToBounds = true
imageView.contentMode = .scaleAspectFill
return imageView
}()
private lazy var nicknameLabel: UILabel = {
let label = UILabel()
label.font = .systemFont(ofSize: 16, weight: .medium)
return label
}()
private lazy var followButton: UIButton = {
let button = UIButton(type: .system)
button.layer.cornerRadius = 15
button.clipsToBounds = true
return button
}()
init(author: YHVideoAuthor) {
self.author = author
super.init(frame: .zero)
setupUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupUI() {
addSubview(avatarImageView)
addSubview(nicknameLabel)
addSubview(followButton)
// 设置约束
avatarImageView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(16)
make.centerY.equalToSuperview()
make.size.equalTo(CGSize(width: 40, height: 40))
}
nicknameLabel.snp.makeConstraints { make in
make.left.equalTo(avatarImageView.snp.right).offset(12)
make.centerY.equalToSuperview()
}
followButton.snp.makeConstraints { make in
make.right.equalToSuperview().offset(-16)
make.centerY.equalToSuperview()
make.width.equalTo(80)
make.height.equalTo(30)
}
// 设置数据
nicknameLabel.text = author.nickname
updateFollowButton()
// 加载头像
if let avatarUrl = author.avatarUrl {
// 使用SDWebImage或其他图片加载库加载头像
// avatarImageView.sd_setImage(with: URL(string: avatarUrl))
}
}
private func updateFollowButton() {
let title = author.isFollowed ? "已关注" : "关注"
let backgroundColor = author.isFollowed ? UIColor.systemGray3 : UIColor.systemBlue
followButton.setTitle(title, for: .normal)
followButton.backgroundColor = backgroundColor
followButton.setTitleColor(.white, for: .normal)
}
}
//
// YHMediaProtocolUtils.swift
// galaxy
//
// Created by alexzzw on 2024/11/24.
// Copyright © 2024 https://www.galaxy-immi.com. All rights reserved.
//
import Foundation
// MARK: - Protocols
protocol YHMediaPlayerViewDelegate: AnyObject {
func didTapPlayButton()
func didTapStopButton()
func didSeekToPosition(_ position: Float)
func didChangeQuality(_ quality: YHVideoQuality)
func didToggleFullscreen()
}
// MARK: - Enums
enum YHVideoQuality: String, CaseIterable {
case auto = "自动"
case sd = "标清"
case hd = "高清"
case fhd = "超清"
}
enum YHPlayerStatus {
case idle
case playing
case paused
case stopped
case error(String)
}
// MARK: - Data Models
struct YHLiveRoomInfo {
let roomId: String
let anchorId: String
let anchorName: String
let streamUrl: String
let title: String
let coverUrl: String?
var currentQuality: YHVideoQuality = .auto
var viewerCount: Int = 0
var likeCount: Int = 0
var status: YHLiveRoomStatus = .idle
}
enum YHLiveRoomStatus {
case idle
case living
case ended
case error(String)
}
struct YHLiveMessage {
let id: String = UUID().uuidString
let type: YHLiveMessageType
let sender: YHLiveUser
let content: String
let timestamp: Date
static func createNormalMessage(sender: YHLiveUser, content: String) -> YHLiveMessage {
return YHLiveMessage(type: .normal, sender: sender, content: content, timestamp: Date())
}
static func createSystemMessage(_ content: String) -> YHLiveMessage {
let system = YHLiveUser(userId: "system", nickname: "系统", level: 0, isAdmin: true)
return YHLiveMessage(type: .system, sender: system, content: content, timestamp: Date())
}
}
enum YHLiveMessageType {
case normal // 普通消息
case system // 系统消息
case gift // 礼物消息
case enter // 进入消息
case like // 点赞消息
}
struct YHLiveUser {
let userId: String
let nickname: String
let level: Int
let isAdmin: Bool
var avatar: String?
}
// MARK: - Video Models
struct YHVideoInfo {
let videoId: String
let title: String
let description: String?
let coverUrl: String?
let duration: Int // 视频时长(秒)
let createTime: Date // 创建时间
var playCount: Int // 播放次数
let category: YHVideoCategory
let author: YHVideoAuthor
let videoUrls: [YHVideoQualityURL] // 不同清晰度的视频地址
// 获取指定清晰度的视频URL
func getVideoUrl(for quality: YHVideoQuality) -> String? {
return videoUrls.first { $0.quality == quality }?.url
}
// 获取最佳清晰度(根据网络情况)
func getBestQualityUrl(for networkType: YHNetworkType) -> String? {
switch networkType {
case .wifi:
return videoUrls.sorted { $0.quality.rawValue > $1.quality.rawValue }.first?.url
case .cellular:
return videoUrls.first { $0.quality == .sd }?.url
case .none:
return videoUrls.first { $0.quality == .sd }?.url
}
}
}
// 视频作者信息
struct YHVideoAuthor {
let userId: String
let nickname: String
let avatarUrl: String?
let description: String?
var followerCount: Int
var isFollowed: Bool
}
// 视频分类
enum YHVideoCategory: String {
case entertainment = "娱乐"
case sports = "体育"
case news = "新闻"
case education = "教育"
case gaming = "游戏"
case music = "音乐"
case other = "其他"
}
// 不同清晰度的视频URL
struct YHVideoQualityURL {
let quality: YHVideoQuality
let url: String
let bitrate: Int // 比特率
let resolution: YHVideoResolution
}
// 视频分辨率
struct YHVideoResolution {
let width: Int
let height: Int
var description: String {
return "\(width)x\(height)"
}
}
// 网络类型
enum YHNetworkType {
case wifi
case cellular
case none
}
// 视频播放相关的配置
struct YHVideoPlayConfig {
var autoPlay: Bool = true // 自动播放
var loopPlay: Bool = false // 循环播放
var muteOnStart: Bool = false // 开始时静音
var preferredQuality: YHVideoQuality = .auto // 首选清晰度
var enableBackgroundPlay: Bool = false // 允许后台播放
}
// 视频播放状态
enum YHVideoPlayState {
case idle // 空闲
case loading // 加载中
case playing // 播放中
case paused // 暂停
case ended // 结束
case error(String) // 错误
}
// 视频播放进度信息
struct YHVideoProgress {
let currentTime: TimeInterval
let duration: TimeInterval
var progress: Float {
return duration > 0 ? Float(currentTime / duration) : 0
}
}
//
// YHLiveMessageCell.swift
// galaxy
//
// Created by alexzzw on 2024/11/25.
// Copyright © 2024 https://www.galaxy-immi.com. All rights reserved.
//
import UIKit
class YHLiveMessageCell: UITableViewCell {
static let reuseIdentifier = "YHLiveMessageCell"
// MARK: - UI Components
private let containerView: UIView = {
let view = UIView()
view.backgroundColor = UIColor.black.withAlphaComponent(0.4)
view.layer.cornerRadius = 8
return view
}()
private let levelLabel: YHPaddedLabel = {
let label = YHPaddedLabel(padding: UIEdgeInsets(top: 2, left: 4, bottom: 2, right: 4))
label.font = .systemFont(ofSize: 10)
label.textColor = .white
label.backgroundColor = .systemBlue
label.layer.cornerRadius = 4
label.layer.masksToBounds = true
return label
}()
private let nicknameLabel: UILabel = {
let label = UILabel()
label.font = .systemFont(ofSize: 14, weight: .medium)
label.textColor = .systemYellow
return label
}()
private let contentLabel: UILabel = {
let label = UILabel()
label.font = .systemFont(ofSize: 14)
label.textColor = .white
label.numberOfLines = 0
return label
}()
// MARK: - Initialization
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupUI() {
backgroundColor = .clear
selectionStyle = .none
contentView.addSubview(containerView)
containerView.addSubview(levelLabel)
containerView.addSubview(nicknameLabel)
containerView.addSubview(contentLabel)
setupConstraints()
}
private func setupConstraints() {
containerView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(8)
make.right.lessThanOrEqualToSuperview().offset(-8)
make.top.equalToSuperview().offset(4)
make.bottom.equalToSuperview().offset(-4)
}
levelLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(8)
make.centerY.equalTo(nicknameLabel)
}
nicknameLabel.snp.makeConstraints { make in
make.left.equalTo(levelLabel.snp.right).offset(8)
make.top.equalToSuperview().offset(8)
}
contentLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(8)
make.right.equalToSuperview().offset(-8)
make.top.equalTo(nicknameLabel.snp.bottom).offset(4)
make.bottom.equalToSuperview().offset(-8)
}
}
// MARK: - Configuration
func configure(with message: YHLiveMessage) {
levelLabel.text = "Lv.\(message.sender.level)"
nicknameLabel.text = message.sender.nickname
switch message.type {
case .normal:
configureNormalMessage(message)
case .system:
configureSystemMessage(message)
case .gift:
configureGiftMessage(message)
case .enter:
configureEnterMessage(message)
case .like:
configureLikeMessage(message)
}
}
private func configureNormalMessage(_ message: YHLiveMessage) {
contentLabel.text = message.content
contentLabel.textColor = .white
if message.sender.isAdmin {
nicknameLabel.textColor = .systemRed
} else {
nicknameLabel.textColor = .systemYellow
}
}
private func configureSystemMessage(_ message: YHLiveMessage) {
levelLabel.isHidden = true
nicknameLabel.isHidden = true
contentLabel.text = message.content
contentLabel.textColor = .systemGray
contentLabel.textAlignment = .center
}
private func configureGiftMessage(_ message: YHLiveMessage) {
contentLabel.text = message.content
contentLabel.textColor = .systemPink
}
private func configureEnterMessage(_ message: YHLiveMessage) {
contentLabel.text = "进入了直播间"
contentLabel.textColor = .systemGreen
}
private func configureLikeMessage(_ message: YHLiveMessage) {
contentLabel.text = "点了赞"
contentLabel.textColor = .systemPink
}
}
//
// YHLiveMessageListView.swift
// galaxy
//
// Created by alexzzw on 2024/11/25.
// Copyright © 2024 https://www.galaxy-immi.com. All rights reserved.
//
import UIKit
class YHLiveMessageListView: UIView {
// MARK: - Properties
private var messages: [YHLiveMessage] = []
private let maxMessageCount = 200
// MARK: - UI Components
private lazy var tableView: UITableView = {
let tableView = UITableView()
tableView.backgroundColor = .clear
tableView.separatorStyle = .none
tableView.showsVerticalScrollIndicator = false
tableView.allowsSelection = false
tableView.delegate = self
tableView.dataSource = self
tableView.register(YHLiveMessageCell.self, forCellReuseIdentifier: YHLiveMessageCell.reuseIdentifier)
return tableView
}()
private lazy var messageInputView: YHMessageInputView = {
let view = YHMessageInputView(frame: CGRect.zero)
view.delegate = self
return view
}()
// MARK: - Initialization
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupUI() {
backgroundColor = .clear
addSubview(tableView)
addSubview(messageInputView)
setupConstraints()
}
private func setupConstraints() {
tableView.snp.makeConstraints { make in
make.top.left.right.equalToSuperview()
make.bottom.equalTo(messageInputView.snp.top)
}
messageInputView.snp.makeConstraints { make in
make.left.right.bottom.equalToSuperview()
make.height.equalTo(44)
}
}
// MARK: - Public Methods
func addMessage(_ message: YHLiveMessage) {
messages.append(message)
if messages.count > maxMessageCount {
messages.removeFirst(messages.count - maxMessageCount)
}
let indexPath = IndexPath(row: messages.count - 1, section: 0)
tableView.insertRows(at: [indexPath], with: .fade)
scrollToBottom(animated: true)
}
func clearMessages() {
messages.removeAll()
tableView.reloadData()
}
private func scrollToBottom(animated: Bool) {
guard !messages.isEmpty else { return }
let lastIndex = IndexPath(row: messages.count - 1, section: 0)
tableView.scrollToRow(at: lastIndex, at: .bottom, animated: animated)
}
}
// MARK: - UITableViewDelegate & UITableViewDataSource
extension YHLiveMessageListView: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return messages.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(
withIdentifier: YHLiveMessageCell.reuseIdentifier,
for: indexPath) as? YHLiveMessageCell else {
return UITableViewCell()
}
let message = messages[indexPath.row]
cell.configure(with: message)
return cell
}
}
// MARK: - MessageInputViewDelegate
extension YHLiveMessageListView: YHMessageInputViewDelegate {
func messageInputView(_ inputView: YHMessageInputView, didSendMessage text: String) {
// 创建当前用户
let currentUser = YHLiveUser(userId: "current_user",
nickname: "我",
level: 1,
isAdmin: false)
// 创建消息
let message = YHLiveMessage.createNormalMessage(sender: currentUser,
content: text)
// 添加消息到列表
addMessage(message)
}
}
//
// YHMessageInputView.swift
// galaxy
//
// Created by alexzzw on 2024/11/25.
// Copyright © 2024 https://www.galaxy-immi.com. All rights reserved.
//
import UIKit
protocol YHMessageInputViewDelegate: AnyObject {
func messageInputView(_ inputView: YHMessageInputView, didSendMessage text: String)
}
class YHMessageInputView: UIView {
// MARK: - Properties
weak var delegate: YHMessageInputViewDelegate?
// MARK: - UI Components
private lazy var textField: UITextField = {
let textField = UITextField()
textField.placeholder = "说点什么..."
textField.textColor = .white
textField.backgroundColor = UIColor.white.withAlphaComponent(0.2)
textField.layer.cornerRadius = 17
textField.leftView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: 34))
textField.leftViewMode = .always
textField.returnKeyType = .send
textField.delegate = self
return textField
}()
private lazy var sendButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("发送", for: .normal)
button.setTitleColor(.white, for: .normal)
button.addTarget(self, action: #selector(sendButtonTapped), for: .touchUpInside)
return button
}()
// MARK: - Initialization
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupUI() {
backgroundColor = UIColor.black.withAlphaComponent(0.4)
addSubview(textField)
addSubview(sendButton)
setupConstraints()
}
private func setupConstraints() {
textField.snp.makeConstraints { make in
make.left.equalToSuperview().offset(8)
make.centerY.equalToSuperview()
make.right.equalTo(sendButton.snp.left).offset(-8)
make.height.equalTo(34)
}
sendButton.snp.makeConstraints { make in
make.right.equalToSuperview().offset(-8)
make.centerY.equalToSuperview()
make.width.equalTo(50)
}
}
@objc private func sendButtonTapped() {
sendMessage()
}
private func sendMessage() {
guard let text = textField.text?.trimmingCharacters(in: .whitespacesAndNewlines),
!text.isEmpty else {
return
}
delegate?.messageInputView(self, didSendMessage: text)
textField.text = ""
}
}
// MARK: - UITextFieldDelegate
extension YHMessageInputView: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
sendMessage()
textField.resignFirstResponder()
return true
}
}
//
// YHPlayerControlView.swift
// galaxy
//
// Created by alexzzw on 2024/11/25.
// Copyright © 2024 https://www.galaxy-immi.com. All rights reserved.
//
import UIKit
class YHPlayerControlView: UIView {
// MARK: - Properties
weak var delegate: YHMediaPlayerViewDelegate?
// MARK: - UI Components
private lazy var topBar: UIView = {
let view = UIView()
view.backgroundColor = UIColor.black.withAlphaComponent(0.5)
return view
}()
private lazy var backButton: UIButton = {
let button = UIButton(type: .system)
button.setImage(UIImage(systemName: "chevron.left"), for: .normal)
button.tintColor = .white
button.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside)
return button
}()
private lazy var titleLabel: UILabel = {
let label = UILabel()
label.textColor = .white
label.font = .systemFont(ofSize: 16, weight: .medium)
return label
}()
private lazy var bottomBar: UIView = {
let view = UIView()
view.backgroundColor = UIColor.black.withAlphaComponent(0.5)
return view
}()
private lazy var playButton: UIButton = {
let button = UIButton(type: .system)
button.setImage(UIImage(systemName: "play.fill"), for: .normal)
button.tintColor = .white
button.addTarget(self, action: #selector(playButtonTapped), for: .touchUpInside)
return button
}()
private lazy var progressSlider: UISlider = {
let slider = UISlider()
slider.minimumTrackTintColor = .systemBlue
slider.maximumTrackTintColor = .gray
slider.setThumbImage(UIImage(systemName: "circle.fill")?.withTintColor(.white, renderingMode: .alwaysOriginal), for: .normal)
slider.addTarget(self, action: #selector(sliderValueChanged(_:)), for: .valueChanged)
return slider
}()
private lazy var timeLabel: UILabel = {
let label = UILabel()
label.textColor = .white
label.font = .systemFont(ofSize: 12)
label.text = "00:00 / 00:00"
return label
}()
private lazy var qualityButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("清晰度", for: .normal)
button.setTitleColor(.white, for: .normal)
button.addTarget(self, action: #selector(qualityButtonTapped), for: .touchUpInside)
return button
}()
private lazy var fullscreenButton: UIButton = {
let button = UIButton(type: .system)
button.setImage(UIImage(systemName: "arrow.up.left.and.arrow.down.right"), for: .normal)
button.tintColor = .white
button.addTarget(self, action: #selector(fullscreenButtonTapped), for: .touchUpInside)
return button
}()
// MARK: - Initialization
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setupUI()
}
// MARK: - Setup
private func setupUI() {
addSubview(topBar)
addSubview(bottomBar)
topBar.addSubview(backButton)
topBar.addSubview(titleLabel)
bottomBar.addSubview(playButton)
bottomBar.addSubview(progressSlider)
bottomBar.addSubview(timeLabel)
bottomBar.addSubview(qualityButton)
bottomBar.addSubview(fullscreenButton)
setupConstraints()
}
private func setupConstraints() {
topBar.snp.makeConstraints { make in
make.top.left.right.equalToSuperview()
make.height.equalTo(44)
}
backButton.snp.makeConstraints { make in
make.left.equalTo(topBar).offset(16)
make.centerY.equalTo(topBar)
make.size.equalTo(CGSize(width: 44, height: 44))
}
titleLabel.snp.makeConstraints { make in
make.center.equalTo(topBar)
}
bottomBar.snp.makeConstraints { make in
make.left.right.bottom.equalToSuperview()
make.height.equalTo(44)
}
playButton.snp.makeConstraints { make in
make.left.equalTo(bottomBar).offset(16)
make.centerY.equalTo(bottomBar)
make.size.equalTo(CGSize(width: 44, height: 44))
}
progressSlider.snp.makeConstraints { make in
make.left.equalTo(playButton.snp.right).offset(8)
make.right.equalTo(timeLabel.snp.left).offset(-8)
make.centerY.equalTo(bottomBar)
}
timeLabel.snp.makeConstraints { make in
make.right.equalTo(qualityButton.snp.left).offset(-8)
make.centerY.equalTo(bottomBar)
make.width.equalTo(100)
}
qualityButton.snp.makeConstraints { make in
make.right.equalTo(fullscreenButton.snp.left).offset(-8)
make.centerY.equalTo(bottomBar)
}
fullscreenButton.snp.makeConstraints { make in
make.right.equalTo(bottomBar).offset(-16)
make.centerY.equalTo(bottomBar)
make.size.equalTo(CGSize(width: 44, height: 44))
}
}
// MARK: - Actions
@objc private func backButtonTapped() {
// Handle back action
}
@objc private func playButtonTapped() {
delegate?.didTapPlayButton()
}
@objc private func sliderValueChanged(_ slider: UISlider) {
delegate?.didSeekToPosition(slider.value)
}
@objc private func qualityButtonTapped() {
showQualitySelector()
}
@objc private func fullscreenButtonTapped() {
delegate?.didToggleFullscreen()
}
private func showQualitySelector() {
let alert = UIAlertController(title: "选择清晰度", message: nil, preferredStyle: .actionSheet)
YHVideoQuality.allCases.forEach { quality in
let action = UIAlertAction(title: quality.rawValue, style: .default) { [weak self] _ in
self?.delegate?.didChangeQuality(quality)
}
alert.addAction(action)
}
alert.addAction(UIAlertAction(title: "取消", style: .cancel))
if let viewController = self.window?.rootViewController {
viewController.present(alert, animated: true)
}
}
}
// MARK: - YHPlayerControlView Extension
extension YHPlayerControlView {
func updatePlayButton(isPlaying: Bool) {
let imageName = isPlaying ? "pause.fill" : "play.fill"
playButton.setImage(UIImage(systemName: imageName), for: .normal)
}
func updateProgress(_ progress: Float, currentTime: String, totalTime: String) {
progressSlider.value = progress
timeLabel.text = "\(currentTime) / \(totalTime)"
}
func setTitle(_ title: String) {
titleLabel.text = title
}
func showControls(_ show: Bool) {
UIView.animate(withDuration: 0.3) {
self.alpha = show ? 1.0 : 0.0
}
}
}
...@@ -228,6 +228,11 @@ extension YhConstant { ...@@ -228,6 +228,11 @@ extension YhConstant {
} }
struct AgoraRtcKit {
static let appId: String = "f1da9c5b9fb946148761278273f43a14"
static let certificate: String? = "1776134c2dcb4d60bc3d1983fef02212"
}
// MARK: - 通知相关 名称 // MARK: - 通知相关 名称
class YhNotification { class YhNotification {
//登录成功 //登录成功
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment