├── .DS_Store
├── Package.swift
├── README-zh_CN.md
├── README.md
├── SDK
├── README-zh_CN.md
└── README.md
├── Sources
└── TXLiteAVSDK_TRTC_SPM
│ └── trtc_swift_package.swift
├── TRTC-API-Example-OC
├── .DS_Store
├── Advanced
│ ├── CustomCamera
│ │ ├── CustomCaptureViewController.h
│ │ ├── CustomCaptureViewController.m
│ │ ├── CustomCaptureViewController.xib
│ │ └── Helper
│ │ │ ├── CustomCameraHelper.h
│ │ │ ├── CustomCameraHelper.m
│ │ │ └── Render
│ │ │ ├── AVCamPreviewView.h
│ │ │ ├── AVCamPreviewView.m
│ │ │ ├── CustomCameraFrameRender.h
│ │ │ └── CustomCameraFrameRender.m
│ ├── JoinMultipleRoom
│ │ ├── JoinMultipleRoomViewController.h
│ │ ├── JoinMultipleRoomViewController.m
│ │ ├── JoinMultipleRoomViewController.xib
│ │ ├── SubCloudHelper.h
│ │ └── SubCloudHelper.m
│ ├── LocalRecord
│ │ ├── LocalRecordViewController.h
│ │ ├── LocalRecordViewController.m
│ │ └── LocalRecordViewController.xib
│ ├── LocalVideoShare
│ │ ├── LocalVideoShareViewController.h
│ │ ├── LocalVideoShareViewController.m
│ │ ├── LocalVideoShareViewController.xib
│ │ └── helper
│ │ │ ├── CustomFrameRender.h
│ │ │ ├── CustomFrameRender.m
│ │ │ ├── MediaFileSyncReader.h
│ │ │ ├── MediaFileSyncReader.m
│ │ │ ├── player
│ │ │ ├── AudioQueuePlay.h
│ │ │ └── AudioQueuePlay.m
│ │ │ └── reader
│ │ │ ├── MediaFileReader.h
│ │ │ └── MediaFileReader.m
│ ├── PictureInPicture
│ │ ├── PictureInPictureViewController.h
│ │ ├── PictureInPictureViewController.m
│ │ └── PictureInPictureViewController.xib
│ ├── PushCDN
│ │ ├── PushCDNAnchorViewController.h
│ │ ├── PushCDNAnchorViewController.m
│ │ ├── PushCDNAnchorViewController.xib
│ │ ├── PushCDNAudienceViewController.h
│ │ ├── PushCDNAudienceViewController.m
│ │ ├── PushCDNAudienceViewController.xib
│ │ ├── PushCDNSelectRoleViewController.h
│ │ ├── PushCDNSelectRoleViewController.m
│ │ └── PushCDNSelectRoleViewController.xib
│ ├── RoomPk
│ │ ├── RoomPkViewController.h
│ │ ├── RoomPkViewController.m
│ │ └── RoomPkViewController.xib
│ ├── SEIMessage
│ │ ├── SendAndReceiveSEIMessageViewController.h
│ │ ├── SendAndReceiveSEIMessageViewController.m
│ │ └── SendAndReceiveSEIMessageViewController.xib
│ ├── SetAudioEffect
│ │ ├── SetAudioEffectViewController.h
│ │ ├── SetAudioEffectViewController.m
│ │ └── SetAudioEffectViewController.xib
│ ├── SetAudioQuality
│ │ ├── SetAudioQualityViewController.h
│ │ ├── SetAudioQualityViewController.m
│ │ └── SetAudioQualityViewController.xib
│ ├── SetBackgroundMusic
│ │ ├── SetBGMViewController.h
│ │ ├── SetBGMViewController.m
│ │ └── SetBGMViewController.xib
│ ├── SetRenderParams
│ │ ├── SetRenderParamsViewController.h
│ │ ├── SetRenderParamsViewController.m
│ │ └── SetRenderParamsViewController.xib
│ ├── SetVideoQuality
│ │ ├── SetVideoQualityViewController.h
│ │ ├── SetVideoQualityViewController.m
│ │ └── SetVideoQualityViewController.xib
│ ├── SpeedTest
│ │ ├── SpeedTestViewController.h
│ │ ├── SpeedTestViewController.m
│ │ └── SpeedTestViewController.xib
│ ├── StringRoomId
│ │ ├── StringRoomIdViewController.h
│ │ ├── StringRoomIdViewController.m
│ │ └── StringRoomIdViewController.xib
│ ├── SwitchRoom
│ │ ├── SwitchRoomViewController.h
│ │ ├── SwitchRoomViewController.m
│ │ └── SwitchRoomViewController.xib
│ └── ThirdBeauty
│ │ ├── README-zh_CN.md
│ │ ├── README.md
│ │ ├── ThirdBeautyBytedViewController.h
│ │ ├── ThirdBeautyBytedViewController.m
│ │ ├── ThirdBeautyBytedViewController.xib
│ │ ├── ThirdBeautyEntranceViewController.h
│ │ ├── ThirdBeautyEntranceViewController.m
│ │ ├── ThirdBeautyEntranceViewController.xib
│ │ ├── ThirdBeautyFaceunityViewController.h
│ │ ├── ThirdBeautyFaceunityViewController.m
│ │ ├── ThirdBeautyFaceunityViewController.xib
│ │ ├── ThirdBeautyTencentEffectViewController.h
│ │ ├── ThirdBeautyTencentEffectViewController.m
│ │ └── ThirdBeautyTencentEffectViewController.xib
├── App
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── Extension
│ │ ├── NSString+Common.h
│ │ ├── NSString+Common.m
│ │ ├── UIColor+Hex.h
│ │ ├── UIColor+Hex.m
│ │ ├── UIViewController+AlertViewController.h
│ │ └── UIViewController+AlertViewController.m
│ ├── Home
│ │ ├── HomeTableViewCell.h
│ │ ├── HomeTableViewCell.m
│ │ ├── HomeTableViewCell.xib
│ │ ├── ViewController.h
│ │ └── ViewController.m
│ ├── Info.plist
│ ├── PCH
│ │ └── TRTC-API-Example-OC-PrefixHeader.pch
│ ├── SceneDelegate.h
│ ├── SceneDelegate.m
│ └── main.m
├── Basic
│ ├── AudioCall
│ │ ├── AudioCallingEnterViewController.h
│ │ ├── AudioCallingEnterViewController.m
│ │ ├── AudioCallingEnterViewController.xib
│ │ ├── AudioCallingViewController.h
│ │ ├── AudioCallingViewController.m
│ │ └── AudioCallingViewController.xib
│ ├── Live
│ │ ├── LiveAnchorViewController.h
│ │ ├── LiveAnchorViewController.m
│ │ ├── LiveAnchorViewController.xib
│ │ ├── LiveAudienceViewController.h
│ │ ├── LiveAudienceViewController.m
│ │ ├── LiveAudienceViewController.xib
│ │ ├── LiveEnterViewController.h
│ │ ├── LiveEnterViewController.m
│ │ └── LiveEnterViewController.xib
│ ├── ScreenShare
│ │ ├── ScreenAnchorViewController.h
│ │ ├── ScreenAnchorViewController.m
│ │ ├── ScreenAnchorViewController.xib
│ │ ├── ScreenAudienceViewController.h
│ │ ├── ScreenAudienceViewController.m
│ │ ├── ScreenAudienceViewController.xib
│ │ ├── ScreenEntranceViewController.h
│ │ ├── ScreenEntranceViewController.m
│ │ ├── ScreenEntranceViewController.xib
│ │ ├── TRTCBroadcastExtensionLauncher.h
│ │ ├── TRTCBroadcastExtensionLauncher.m
│ │ └── TXReplayKit_Screen
│ │ │ ├── Info.plist
│ │ │ ├── SampleHandler.h
│ │ │ └── SampleHandler.m
│ ├── VideoCall
│ │ ├── VideoCallingEnterViewController.h
│ │ ├── VideoCallingEnterViewController.m
│ │ ├── VideoCallingEnterViewController.xib
│ │ ├── VideoCallingViewController.h
│ │ ├── VideoCallingViewController.m
│ │ └── VideoCallingViewController.xib
│ └── VoiceChatRoom
│ │ ├── VoiceChatRoomAnchorViewController.h
│ │ ├── VoiceChatRoomAnchorViewController.m
│ │ ├── VoiceChatRoomAnchorViewController.xib
│ │ ├── VoiceChatRoomAudienceViewController.h
│ │ ├── VoiceChatRoomAudienceViewController.m
│ │ ├── VoiceChatRoomAudienceViewController.xib
│ │ ├── VoiceChatRoomEnterViewController.h
│ │ ├── VoiceChatRoomEnterViewController.m
│ │ └── VoiceChatRoomEnterViewController.xib
├── Debug
│ ├── GenerateTestUserSig.h
│ ├── GenerateTestUserSig.m
│ ├── UIViewController+KeyBoard.h
│ └── UIViewController+KeyBoard.m
├── Podfile
├── Podfile.lock
├── README-zh_CN.md
├── README.md
├── Resource
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ ├── AppIcon1024x1024.png
│ │ │ ├── AppIcon120x120.png
│ │ │ └── Contents.json
│ │ ├── Contents.json
│ │ ├── audiocall_user_portrait.imageset
│ │ │ ├── Contents.json
│ │ │ ├── audiocall_user_portrait-1.png
│ │ │ └── audiocall_user_portrait.png
│ │ └── launchimage.imageset
│ │ │ ├── Contents.json
│ │ │ ├── launchimage@2x.png
│ │ │ └── launchimage@3x.png
│ └── Localized
│ │ ├── AppLocalized.h
│ │ ├── AppLocalized.m
│ │ ├── en.lproj
│ │ ├── InfoPlist.strings
│ │ └── Localized.strings
│ │ └── zh-Hans.lproj
│ │ ├── InfoPlist.strings
│ │ └── Localized.strings
├── TRTC-API-Example-OC.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcuserdata
│ │ │ └── tangjianing.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ ├── xcshareddata
│ │ └── xcschemes
│ │ │ ├── TRTC-API-Example-OC.xcscheme
│ │ │ └── TXReplayKit_Screen.xcscheme
│ └── xcuserdata
│ │ └── tangjianing.xcuserdatad
│ │ └── xcschemes
│ │ ├── Copy of Copy of TRTC-API-Example-OC.xcscheme
│ │ ├── Copy of TRTC-API-Example-OC.xcscheme
│ │ └── xcschememanagement.plist
└── TRTC-API-Example-OC.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcshareddata
│ └── IDEWorkspaceChecks.plist
│ └── xcuserdata
│ └── wangyan.xcuserdatad
│ └── UserInterfaceState.xcuserstate
└── TRTC-API-Example-Swift
├── .DS_Store
├── .gitignore
├── .gitkeep
├── Advanced
├── .gitkeep
├── CustomCamera
│ ├── CustomCaptureViewController.swift
│ ├── Helper
│ │ └── CustomCameraHelper.swift
│ └── Render
│ │ └── CustomCameraFrameRender.swift
├── JoinMultipleRoom
│ ├── JoinMultipleRoomViewController.swift
│ └── SubCloudHelper.swift
├── LocalRecord
│ └── LocalRecordViewController.swift
├── PictureInPicture
│ └── PictureInPictureViewController.swift
├── PushCDN
│ ├── PushCDNAnchorViewController.swift
│ ├── PushCDNAudienceViewController.swift
│ └── PushCDNSelectRoleViewController.swift
├── RoomPk
│ └── RoomPkViewController.swift
├── SEIMessage
│ └── SendAndReceiveSEIMessageViewController.swift
├── SetAudioEffect
│ └── SetAudioEffectViewController.swift
├── SetAudioQuality
│ └── SetAudioQualityViewController.swift
├── SetBackgroundMusic
│ └── SetBGMViewController.swift
├── SetRenderParams
│ └── SetRenderParamsViewController.swift
├── SetVideoQuality
│ └── SetVideoQualityViewController.swift
├── SpeedTest
│ └── SpeedTestViewController.swift
├── StringRoomId
│ └── StringRoomIdViewController.swift
└── SwitchRoom
│ └── SwitchRoomViewController.swift
├── App
├── AppDelegate.swift
├── Extension
│ └── UIColor+hex.swift
├── Home
│ ├── HomeViewController.swift
│ └── SubViews
│ │ ├── HomeTableSectionHeaderView.swift
│ │ └── HomeTableViewCell.swift
├── Info.plist
└── SceneDelegate.swift
├── Basic
├── .gitkeep
├── AudioCall
│ ├── AudioCallingEnterViewController.swift
│ └── AudioCallingViewController.swift
├── Live
│ ├── LiveAnchorViewController.swift
│ ├── LiveAudienceViewController.swift
│ └── LiveEnterViewController.swift
├── ScreenShare
│ ├── ScreenAnchorViewController.swift
│ ├── ScreenAudienceViewController.swift
│ ├── ScreenEntranceViewController.swift
│ └── TRTCBroadcastExtensionLauncher.swift
├── VideoCall
│ ├── VideoCallingEnterViewController.swift
│ └── VideoCallingViewController.swift
└── VioceChatRoom
│ ├── VoiceChatRoomAnchorViewController.swift
│ ├── VoiceChatRoomAudienceViewController.swift
│ └── VoiceChatRoomEnterViewController.swift
├── Debug
├── .gitkeep
└── GenerateTestUserSig.swift
├── README-zh_CN.md
├── README.md
├── Resource
├── Assets.xcassets
│ ├── AccentColor.colorset
│ │ └── Contents.json
│ ├── AppIcon.appiconset
│ │ ├── AppIcon1024x1024.png
│ │ ├── AppIcon120x120-1.png
│ │ ├── AppIcon120x120.png
│ │ └── Contents.json
│ ├── Contents.json
│ └── audiocall_user_portrait.imageset
│ │ ├── Contents.json
│ │ ├── audiocall_user_portrait-1.png
│ │ └── audiocall_user_portrait.png
├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
└── Localized
│ └── Localize
│ ├── Localized.swift
│ ├── en.lproj
│ ├── InfoPlist.strings
│ └── Localized.strings
│ └── zh-Hans.lproj
│ ├── InfoPlist.strings
│ └── Localized.strings
└── TRTC-API-Example-Swift.xcodeproj
├── project.pbxproj
├── project.xcworkspace
├── contents.xcworkspacedata
└── xcshareddata
│ ├── IDEWorkspaceChecks.plist
│ └── swiftpm
│ └── Package.resolved
└── xcshareddata
└── xcschemes
└── TRTC-API-Example-Swift.xcscheme
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tencent-RTC/TRTC_iOS/ff2c8291d9f408269d19e5b30f7e4c56463210ea/.DS_Store
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.3
2 | import PackageDescription
3 |
4 | let package = Package(
5 | name: "TRTCKit",
6 | platforms: [
7 | .iOS(.v9)
8 | ],
9 | products: [
10 | .library(
11 | name: "TRTC",
12 | targets: ["TXLiteAVSDK_TRTC_SPM", "TXSoundTouch", "TXFFmpeg"]),
13 | .library(
14 | name: "TRTCReplayKitExt",
15 | targets: ["TXLiteAVSDK_ReplayKitExt"]),
16 | ],
17 | dependencies: [
18 | ],
19 | targets: [
20 | .binaryTarget(
21 | name: "TXLiteAVSDK_TRTC",
22 | url: "https://sdk-liteav-1252463788.cos.ap-hongkong.myqcloud.com/customer/HelperTest/SPM/TXLiteAVSDK_TRTC.xcframework.zip",
23 | checksum: "48269bdbfa4b1c374f5016ed142962c848b7036578ad01f09331ff9a94208725"
24 | ),
25 | .binaryTarget(
26 | name: "TXSoundTouch",
27 | url: "https://sdk-liteav-1252463788.cos.ap-hongkong.myqcloud.com/customer/HelperTest/SPM/TXSoundTouch.xcframework.zip",
28 | checksum: "4870aebc2758afd0f0756db0f4baa478338c45dde6fa45cf2fd7a9b5c5b76ff5"
29 | ),
30 | .binaryTarget(
31 | name: "TXFFmpeg",
32 | url: "https://sdk-liteav-1252463788.cos.ap-hongkong.myqcloud.com/customer/HelperTest/SPM/TXFFmpeg.xcframework.zip",
33 | checksum: "a9cebf1f50587f9dca69d5ba61c9a2c20a6a80090369056365d2bead660a6e4e"
34 | ),
35 | .binaryTarget(
36 | name: "TXLiteAVSDK_ReplayKitExt",
37 | url: "https://sdk-liteav-1252463788.cos.ap-hongkong.myqcloud.com/customer/HelperTest/SPM/TXLiteAVSDK_ReplayKitExt.xcframework.zip",
38 | checksum: "1fa5402691bc4150c73d4535ec040ca54f2859af74af9ef8a80605a9b302284d"
39 | ),
40 | .target(
41 | name: "TXLiteAVSDK_TRTC_SPM",
42 | dependencies: [
43 | .target(name: "TXLiteAVSDK_TRTC")
44 | ],
45 | sources: ["trtc_swift_package.swift"],
46 | linkerSettings: [
47 | .linkedFramework("SystemConfiguration"),
48 | .linkedFramework("CoreTelephony"),
49 | .linkedFramework("CoreServices"),
50 | .linkedFramework("Accelerate"),
51 | .linkedFramework("ReplayKit"),
52 | .linkedLibrary("c++")
53 | ]
54 | )
55 | ]
56 | )
57 |
--------------------------------------------------------------------------------
/README-zh_CN.md:
--------------------------------------------------------------------------------
1 | # 腾讯云实时音视频 TRTC SDK
2 |
3 | _[English](README.md) | 简体中文_
4 |
5 | ## 产品介绍
6 |
7 | 腾讯实时音视频(Tencent Real-Time Communication,TRTC),将腾讯多年来在网络与音视频技术上的深度积累,以多人音视频通话和低延时互动直播两大场景化方案,通过腾讯云服务向开发者开放,致力于帮助开发者快速搭建低成本、低延时、高品质的音视频互动解决方案,[更多](https://cloud.tencent.com/document/product/647/16788)...
8 |
9 | > TRTC SDK 支持Web、Android、iOS、Windows、Flutter、小程序等所有主流平台, [更多平台](https://github.com/LiteAVSDK?q=TRTC_&type=all&sort=)...
10 |
11 |
12 | ## 目录说明
13 |
14 | 本目录包含 iOS 版 TRTC-API-Example 源代码:
15 | - TRTC-API-Example-OC: 最简单的示例代码,使用Objective-C语言。包括视频通话、语音通话的基础功能以及一些高级功能。
16 | ```
17 | ├─ TRTC-API-Example-OC // TRTC API Example,包括视频通话、语音通话的基础功能以及一些高级功能
18 | │ ├─ Basic // 演示 TRTC 基本功能示例代码
19 | │ │ ├─ AudioCall // 演示 TRTC 音频通话的示例代码
20 | │ │ ├─ VideoCall // 演示 TRTC 视频通话的示例代码
21 | │ │ ├─ Live // 演示 TRTC 视频互动直播的示例代码
22 | │ │ ├─ VoiceChatRoom // 演示 TRTC 语音互动直播的示例代码
23 | │ │ ├─ ScreenShare // 演示 TRTC 录屏直播的示例代码
24 | │ ├─ Advanced // 演示 TRTC 高级功能示例代码
25 | │ │ ├─ StringRoomId // 演示 TRTC 字符串房间号示例代码
26 | │ │ ├─ SetVideoQuality // 演示 TRTC 画质设定示例代码
27 | │ │ ├─ SetAudioQuality // 演示 TRTC 音质设定示例代码
28 | │ │ ├─ SetRenderParams // 演示 TRTC 渲染控制示例代码
29 | │ │ ├─ SpeedTest // 演示 TRTC 网络测速示例代码
30 | │ │ ├─ PushCDN // 演示 TRTC CDN发布示例代码
31 | │ │ ├─ CustomCamera // 演示 TRTC 自定义视频采集&渲染发布示例代码
32 | │ │ ├─ SetAudioEffect // 演示 TRTC 设置音效示例代码
33 | │ │ ├─ SetBackgroundMusic // 演示 TRTC 设置背景音乐示例代码
34 | │ │ ├─ LocalVideoShare // 演示 TRTC 本地视频文件分享示例代码
35 | │ │ ├─ LocalRecord // 演示 TRTC 本地视频录制示例代码
36 | │ │ ├─ JoinMultipleRoom // 演示 TRTC 加入多个房间示例代码
37 | │ │ ├─ SEIMessage // 演示 TRTC 收发SEI消息示例代码
38 | │ │ ├─ SwitchRoom // 演示 TRTC 快速切换房间示例代码
39 | │ │ ├─ RoomPk // 演示 TRTC 跨房PK示例代码
40 | │ │ ├─ ThirdBeauty // 演示 TRTC 第三方美颜示例代码
41 | │
42 | ├─ SDK
43 | │ ├─ TXLiteAVSDK_TRTC.framework // 如果您下载的是精简版 zip 包,解压后将出现此文件夹
44 | │ ├─ TXLiteAVSDK_Professional.framework // 如果您下载的是专业版 zip 包,解压后将出现此文件夹
45 | │ ├─ TXLiteAVSDK_Enterprise.framework // 如果您下载的是企业版 zip 包,解压后将出现此文件夹
46 |
47 | ```
48 |
49 |
50 |
51 | ## 联系我们
52 | - 如果你遇到了困难,可以先参阅 [常见问题](https://cloud.tencent.com/document/product/647/43018);
53 |
54 | - 如果你想了解TRTC SDK在复杂场景下的应用,可以参考[更多场景案例](https://cloud.tencent.com/document/product/647/57486);
55 |
56 | - 完整的 API 文档见 [SDK 的 API 文档](https://cloud.tencent.com/document/product/647/32258);
57 | - 如果需要售后技术支持, 你可以点击[这里](https://cloud.tencent.com/document/product/647/19906);
58 | - 如果发现了示例代码的 bug,欢迎提交 issue;
59 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # TRTC SDK
2 |
3 | _[简体中文](README-zh_CN.md) | English_
4 | ## Overview
5 |
6 | Leveraging Tencent's many years of experience in network and audio/video technologies, Tencent Real-Time Communication (TRTC) offers solutions for group audio/video calls and low-latency interactive live streaming. With TRTC, you can quickly develop cost-effective, low-latency, and high-quality interactive audio/video services. [Learn more](https://trtc.io/document)...
7 |
8 | > We offer SDKs for web, Android, iOS, Windows, Flutter, WeChat Mini Program, and [other mainstream platforms](https://github.com/LiteAVSDK?q=TRTC_&type=all&sort=).
9 |
10 |
11 | ## Contents
12 |
13 | This directory contains the TRTC-API-Example source code for iOS:
14 | - TRTC-API-Example-OC: The simplest demos written in Objective-C, including those for basic features such as audio call and video call as well as some advanced features
15 | ```
16 | ├─ TRTC-API-Example-OC // TRTC API examples, including those for basic features such as audio call and video call as well as some advanced features
17 | │ ├─ Basic // Demos for TRTC basic features
18 | │ │ ├─ AudioCall // Demo for audio call in TRTC
19 | │ │ ├─ VideoCall // Demo for video call in TRTC
20 | │ │ ├─ Live // Demo for interactive video live streaming in TRTC
21 | │ │ ├─ VoiceChatRoom // Demo for interactive audio live streaming in TRTC
22 | │ │ ├─ ScreenShare // Demo for screen sharing live streaming in TRTC
23 | │ ├─ Advanced // Demos for TRTC advanced features
24 | │ │ ├─ StringRoomId // Demo for string room ID in TRTC
25 | │ │ ├─ SetVideoQuality // Demo for video quality setting in TRTC
26 | │ │ ├─ SetAudioQuality // Demo for audio quality setting in TRTC
27 | │ │ ├─ SetRenderParams // Demo for rendering control in TRTC
28 | │ │ ├─ SpeedTest // Demo for network speed test in TRTC
29 | │ │ ├─ PushCDN // Demo for CDN push in TRTC
30 | │ │ ├─ CustomCamera // Demo for custom video capturing and rendering in TRTC
31 | │ │ ├─ SetAudioEffect // Demo for sound effect configuration in TRTC
32 | │ │ ├─ SetBackgroundMusic // Demo for background music configuration in TRTC
33 | │ │ ├─ LocalVideoShare // Demo for local video file sharing in TRTC
34 | │ │ ├─ LocalRecord // Demo for local video recording in TRTC
35 | │ │ ├─ JoinMultipleRoom // Demo for multi-room join in TRTC
36 | │ │ ├─ SEIMessage // Demo for SEI message sending/receiving in TRTC
37 | │ │ ├─ SwitchRoom // Demo for quick room switch in TRTC
38 | │ │ ├─ RoomPk // Demo for cross-room competition in TRTC
39 | │ │ ├─ ThirdBeauty // Demo for third-party beauty filters in TRTC
40 | │
41 | ├─ SDK
42 | │ ├─ TXLiteAVSDK_TRTC.framework // If you download the Lite Edition zip package, this folder will appear after decompression
43 | │ ├─ TXLiteAVSDK_Professional.framework // If you download the Pro Edition zip package, this folder will appear after decompression
44 | │ ├─ TXLiteAVSDK_Enterprise.framework // If you download the Enterprise Edition zip package, this folder will appear after decompression
45 |
46 | ```
47 |
48 |
49 |
50 | ## Contact Us
51 | - If you have questions, see [FAQs](https://www.tencentcloud.com/document/product/647/36057).
52 |
53 | - To learn about how the TRTC SDK can be used in different scenarios, see [Sample Code](https://www.tencentcloud.com/document/product/647/42963).
54 |
55 | - For complete API documentation, see [SDK API Documentation](https://www.tencentcloud.com/document/product/647/35119).
56 |
57 | - Communication & Feedback
58 | Welcome to join our Telegram Group to communicate with our professional engineers! We are more than happy to hear from you~
59 | Click to join: [https://t.me/+EPk6TMZEZMM5OGY1](https://t.me/+EPk6TMZEZMM5OGY1)
60 | Or scan the QR code
61 |
62 |
--------------------------------------------------------------------------------
/SDK/README-zh_CN.md:
--------------------------------------------------------------------------------
1 | # TRTC SDK (iOS)
2 |
3 | _[English](README.md) | 简体中文_
4 |
5 | Demo编译时会自动下载SDK到此目录。
6 |
7 | ## 下载地址
8 | - 精简版:[DOWNLOAD](https://liteav.sdk.qcloud.com/download/latest/TXLiteAVSDK_TRTC_iOS_latest.zip)
9 |
--------------------------------------------------------------------------------
/SDK/README.md:
--------------------------------------------------------------------------------
1 | # TRTC iOS SDK
2 | [简体中文](README-zh_CN.md) | English
3 |
4 | When the demo is compiled, the SDK will be automatically downloaded to this directory.
5 |
6 | ## Download URL
7 | - Lite: [Download](https://liteav.sdk.qcloud.com/download/latest/TXLiteAVSDK_TRTC_iOS_latest.zip)
8 |
--------------------------------------------------------------------------------
/Sources/TXLiteAVSDK_TRTC_SPM/trtc_swift_package.swift:
--------------------------------------------------------------------------------
1 | let version = "11.3"
2 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tencent-RTC/TRTC_iOS/ff2c8291d9f408269d19e5b30f7e4c56463210ea/TRTC-API-Example-OC/.DS_Store
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/CustomCamera/CustomCaptureViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // CustomCaptureViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by abyyxwang on 2021/4/22.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 | #import
9 |
10 | NS_ASSUME_NONNULL_BEGIN
11 |
12 | @interface CustomCaptureViewController : UIViewController
13 |
14 | @end
15 |
16 | NS_ASSUME_NONNULL_END
17 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/CustomCamera/Helper/CustomCameraHelper.h:
--------------------------------------------------------------------------------
1 | //
2 | // CustomCameraHelper.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by abyyxwang on 2021/4/22.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
12 |
13 | NS_ASSUME_NONNULL_BEGIN
14 |
15 | @protocol CustomCameraHelperSampleBufferDelegate
16 |
17 | - (void)onVideoSampleBuffer:(CMSampleBufferRef)videoBuffer;
18 |
19 | @end
20 |
21 | @interface CustomCameraHelper : NSObject
22 |
23 | @property (weak, nonatomic)iddelegate;
24 | // set this property before start capture;
25 | @property (assign, nonatomic)UIInterfaceOrientation windowOrientation;
26 |
27 | - (void)checkPermission;
28 |
29 | - (void)createSession;
30 |
31 | - (void)startCameraCapture;
32 |
33 | - (void)stopCameraCapture;
34 |
35 | @end
36 |
37 | NS_ASSUME_NONNULL_END
38 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/CustomCamera/Helper/Render/AVCamPreviewView.h:
--------------------------------------------------------------------------------
1 | //
2 | // TestRenderCustomVideoData.m
3 | // TXLiteAVDemo
4 | //
5 | // Created by rushanting on 2019/3/27.
6 | // Copyright © 2019 Tencent. All rights reserved.
7 | //
8 |
9 | /*
10 | See LICENSE folder for this sample’s licensing information.
11 |
12 | Abstract:
13 | The camera preview view that displays the capture output.
14 | */
15 |
16 | @import UIKit;
17 |
18 | @class AVCaptureSession;
19 |
20 | @interface AVCamPreviewView : UIView
21 |
22 | @property (nonatomic, readonly) AVCaptureVideoPreviewLayer *videoPreviewLayer;
23 |
24 | @property (nonatomic) AVCaptureSession *session;
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/CustomCamera/Helper/Render/AVCamPreviewView.m:
--------------------------------------------------------------------------------
1 | //
2 | // TestRenderCustomVideoData.m
3 | // TXLiteAVDemo
4 | //
5 | // Created by rushanting on 2019/3/27.
6 | // Copyright © 2019 Tencent. All rights reserved.
7 | //
8 |
9 | /*
10 | See LICENSE folder for this sample’s licensing information.
11 |
12 | Abstract:
13 | The camera preview view that displays the capture output.
14 | */
15 |
16 | @import AVFoundation;
17 |
18 | #import "AVCamPreviewView.h"
19 |
20 | @implementation AVCamPreviewView
21 |
22 | + (Class)layerClass
23 | {
24 | return [AVCaptureVideoPreviewLayer class];
25 | }
26 |
27 | - (AVCaptureVideoPreviewLayer*) videoPreviewLayer
28 | {
29 | return (AVCaptureVideoPreviewLayer *)self.layer;
30 | }
31 |
32 | - (AVCaptureSession*) session
33 | {
34 | return self.videoPreviewLayer.session;
35 | }
36 |
37 | - (void)setSession:(AVCaptureSession*) session
38 | {
39 | self.videoPreviewLayer.session = session;
40 | }
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/CustomCamera/Helper/Render/CustomCameraFrameRender.h:
--------------------------------------------------------------------------------
1 | //
2 | // TestRenderCustomVideoData.h
3 | // TXLiteAVDemo
4 | //
5 | // Created by rushanting on 2019/3/27.
6 | // Copyright © 2019 Tencent. All rights reserved.
7 | //
8 | // The incoming userId is nil and is the local screen.
9 |
10 |
11 | #import
12 |
13 | NS_ASSUME_NONNULL_BEGIN
14 |
15 | @interface CustomCameraFrameRender : NSObject
16 |
17 | - (void)start:(nullable NSString*)userId videoView:(UIImageView*)videoView;
18 | - (void)onRenderVideoFrame:(TRTCVideoFrame *)frame userId:(NSString *)userId streamType:(TRTCVideoStreamType)streamType;
19 | - (void)stop;
20 |
21 | @end
22 |
23 | NS_ASSUME_NONNULL_END
24 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/CustomCamera/Helper/Render/CustomCameraFrameRender.m:
--------------------------------------------------------------------------------
1 | //
2 | // TestRenderCustomVideoData.m
3 | // TXLiteAVDemo
4 | //
5 | // Created by rushanting on 2019/3/27.
6 | // Copyright © 2019 Tencent. All rights reserved.
7 | //
8 |
9 | #import "CustomCameraFrameRender.h"
10 |
11 | @interface CustomCameraFrameRender ()
12 | @property (nonatomic, strong) UIImageView* localVideoView;
13 | @property (nonatomic, strong) NSMutableDictionary* userVideoViews;
14 | @property (strong, nonatomic) dispatch_queue_t queue;
15 | @end
16 |
17 | @implementation CustomCameraFrameRender
18 |
19 | - (instancetype)init
20 | {
21 | if (self = [super init]) {
22 | _userVideoViews = [NSMutableDictionary new];
23 | _queue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL);
24 | }
25 |
26 | return self;
27 | }
28 |
29 | - (void)start:(NSString *)userId videoView:(UIImageView *)videoView
30 | {
31 | // userId is nil for self
32 | if (!userId) {
33 | _localVideoView = videoView;
34 | }
35 | else {
36 | [_userVideoViews setObject:videoView forKey:userId];
37 | }
38 | }
39 |
40 | - (void)stop {
41 | UIGraphicsBeginImageContext(_localVideoView.bounds.size);
42 | UIColor * color = [UIColor clearColor];
43 | [color setFill];
44 | UIImage * image = UIGraphicsGetImageFromCurrentImageContext();
45 | UIGraphicsEndImageContext();
46 |
47 | _localVideoView.image = image;
48 | }
49 |
50 | - (void)onRenderVideoFrame:(TRTCVideoFrame *)frame userId:(NSString *)userId streamType:(TRTCVideoStreamType)streamType
51 | {
52 | // When userId is nil, it is the local screen, otherwise it is the remote screen.
53 | CFRetain(frame.pixelBuffer);
54 | __weak __typeof(self) weakSelf = self;
55 | dispatch_async(dispatch_get_main_queue(), ^{
56 | CustomCameraFrameRender* strongSelf = weakSelf;
57 | UIImageView* videoView = nil;
58 | if (userId) {
59 | videoView = [strongSelf.userVideoViews objectForKey:userId];
60 | }
61 | else {
62 | videoView = strongSelf.localVideoView;
63 | }
64 | videoView.image = [UIImage imageWithCIImage:[CIImage imageWithCVImageBuffer:frame.pixelBuffer]];
65 | videoView.contentMode = UIViewContentModeScaleAspectFit;
66 | CFRelease(frame.pixelBuffer);
67 | });
68 | }
69 |
70 | @end
71 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/JoinMultipleRoom/JoinMultipleRoomViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // JoinMultipleRoomViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by bluedang on 2021/4/22.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface JoinMultipleRoomViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/JoinMultipleRoom/SubCloudHelper.h:
--------------------------------------------------------------------------------
1 | //
2 | // SubTRTCCloudHelper.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by bluedang on 2021/4/22.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @protocol SubCloudHelperDelegate
14 |
15 | - (void)onUserVideoAvailableWithSubId:(NSInteger)subId userId:(NSString *)userId available:(BOOL)available;
16 |
17 | @end
18 |
19 | @interface SubCloudHelper : NSObject
20 |
21 | - (instancetype)initWithSubId:(NSInteger)subId cloud:(TRTCCloud*) cloud;
22 | - (TRTCCloud*)getCloud;
23 |
24 | @property (weak, nonatomic) id delegate;
25 |
26 | @end
27 |
28 | NS_ASSUME_NONNULL_END
29 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/JoinMultipleRoom/SubCloudHelper.m:
--------------------------------------------------------------------------------
1 | //
2 | // SubTRTCCloudHelper.m
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by bluedang on 2021/4/22.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import "SubCloudHelper.h"
10 | #import
11 |
12 | @interface SubCloudHelper()
13 | @property (assign, nonatomic) NSInteger subId;
14 | @property (strong, nonatomic) TRTCCloud *trtcCloud;
15 | @end
16 |
17 | @implementation SubCloudHelper
18 |
19 | - (instancetype)initWithSubId:(NSInteger)subId cloud:(TRTCCloud*) cloud {
20 | self = [super init];
21 | _subId = subId;
22 | _trtcCloud = cloud;
23 | [_trtcCloud setDelegate:self];
24 | return self;
25 | }
26 |
27 | - (TRTCCloud *)getCloud {
28 | return _trtcCloud;
29 | }
30 |
31 |
32 | #pragma mark - TRTCCloud Delegate
33 |
34 | - (void)onUserVideoAvailable:(NSString *)userId available:(BOOL)available {
35 | if ([self.delegate respondsToSelector:@selector(onUserVideoAvailableWithSubId:userId:available:)]) {
36 | [self.delegate onUserVideoAvailableWithSubId:self.subId userId:userId available:available];
37 | }
38 | }
39 |
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/LocalRecord/LocalRecordViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // LocalRecordViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by adams on 2021/4/21.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface LocalRecordViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/LocalVideoShare/LocalVideoShareViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // LocalVideoShareViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by bluedang on 2021/4/22.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface LocalVideoShareViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/LocalVideoShare/helper/CustomFrameRender.h:
--------------------------------------------------------------------------------
1 | //
2 | // TestRenderCustomVideoData.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by rushanting on 2019/3/27.
6 | // Copyright © 2019 Tencent. All rights reserved.
7 | //
8 |
9 |
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface CustomFrameRender : NSObject
15 |
16 | + (void)renderImageBuffer:(CVImageBufferRef)imageBufer forView:(UIImageView*)imageView;
17 | + (void)clearImageView:(UIImageView*)imageView;
18 |
19 | @end
20 |
21 | NS_ASSUME_NONNULL_END
22 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/LocalVideoShare/helper/CustomFrameRender.m:
--------------------------------------------------------------------------------
1 | //
2 | // TestRenderCustomVideoData.m
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by rushanting on 2019/3/27.
6 | // Copyright © 2019 Tencent. All rights reserved.
7 | //
8 |
9 | #import "CustomFrameRender.h"
10 |
11 | @implementation CustomFrameRender
12 |
13 | + (void)clearImageView:(UIImageView*)imageView {
14 | dispatch_async(dispatch_get_main_queue(), ^{
15 | UIGraphicsBeginImageContext(imageView.bounds.size);
16 | UIColor * color = [UIColor clearColor];
17 | [color setFill];
18 | UIImage * image = UIGraphicsGetImageFromCurrentImageContext();
19 | imageView.image = image;
20 | UIGraphicsEndImageContext();
21 | });
22 | }
23 |
24 | + (void)renderImageBuffer:(CVImageBufferRef)imageBufer forView:(UIImageView*)imageView {
25 | CFRetain(imageBufer);
26 | dispatch_async(dispatch_get_main_queue(), ^{
27 | imageView.image = [UIImage imageWithCIImage:[CIImage imageWithCVImageBuffer:imageBufer]];
28 | imageView.contentMode = UIViewContentModeScaleAspectFit;
29 | CFRelease(imageBufer);
30 | });
31 | }
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/LocalVideoShare/helper/MediaFileSyncReader.h:
--------------------------------------------------------------------------------
1 | //
2 | // MediaFileSyncReader.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by bluedang on 2021/4/22.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 |
13 | NS_ASSUME_NONNULL_BEGIN
14 |
15 | @protocol MediaFileSyncReaderDelegate
16 |
17 | - (void)onReadVideoFrameAtFrameIntervals:(CVImageBufferRef)imageBuffer timeStamp:(UInt64)timeStamp;
18 | - (void)onReadAudioFrameAtFrameIntervals:(NSData*)pcmData timeStamp:(UInt64)timeStamp;
19 |
20 | @end
21 |
22 | @interface MediaFileSyncReader : NSObject
23 |
24 | @property (weak, nonatomic) id delegate;
25 | @property (atomic, readonly) int audioSampleRate;
26 | @property (atomic, readonly) int audioChannels;
27 | @property (atomic, readonly) float angle;
28 |
29 | - (instancetype)initWithAVAsset:(AVAsset*)asset;
30 |
31 | - (void)start;
32 | - (void)stop;
33 |
34 | @end
35 |
36 | NS_ASSUME_NONNULL_END
37 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/LocalVideoShare/helper/player/AudioQueuePlay.h:
--------------------------------------------------------------------------------
1 | //
2 | // AudioQueuePlay.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by dangjiahe on 2021/4/24.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface AudioQueuePlay : NSObject
14 |
15 | - (void)playWithData: (NSData *)data;
16 | - (void)start;
17 | - (void)stop;
18 |
19 | - (instancetype)init;
20 | @end
21 |
22 | NS_ASSUME_NONNULL_END
23 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/LocalVideoShare/helper/reader/MediaFileReader.h:
--------------------------------------------------------------------------------
1 | //
2 | // AVReader.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by taopu-iMac on 16/12/1.
6 | // Copyright © 2016 qqcloud. All rights reserved.
7 | //
8 |
9 | #ifndef AVReader_h
10 | #define AVReader_h
11 |
12 | #import
13 | #import
14 | #import
15 |
16 | typedef void(^readOneFrame)(CMSampleBufferRef sampleBuffer);
17 | typedef void(^readFinished)(void);
18 |
19 | typedef NS_ENUM(NSInteger,VideoCutType)
20 | {
21 | VideoCutType_None,
22 | VideoCutType_Pieces,
23 | VideoCutType_Duration,
24 | };
25 |
26 | typedef NS_ENUM(NSInteger,VideoReadFormat)
27 | {
28 | VideoReadFormat_NV12,
29 | VideoReadFormat_BGRA,
30 | };
31 |
32 | @interface MediaFileReader : NSObject
33 |
34 | @property (atomic, readonly) CMTime duration;
35 |
36 | @property (atomic, readonly) int bitrate;
37 |
38 | @property (atomic, readonly) float fps;
39 |
40 | @property (atomic, readonly) int width;
41 |
42 | @property (atomic, readonly) int height;
43 |
44 | @property (atomic, readonly) float angle;
45 |
46 | @property (atomic, readonly) int audioSampleRate;
47 |
48 | @property (atomic, readonly) int audioChannels;
49 |
50 | @property (atomic, readonly) int audioBytesPerFrame;
51 |
52 | @property (atomic, readonly) long long totalSampleDataLength;
53 |
54 | @property (atomic, readonly) BOOL hasAudioData;
55 |
56 | @property (atomic, readonly) VideoCutType videoCutType;
57 |
58 | @property (atomic, readonly) BOOL videoCanRead;
59 |
60 | @property (atomic, readonly) BOOL audioCanRead;
61 |
62 | - (instancetype) initWithMediaAsset:(NSObject *)pathAsset videoReadFormat:(VideoReadFormat)videoReadFormat;
63 |
64 | - (void) readVideoFrameFromTime:(float)startTime
65 | toTime:(float)endTime
66 | fps:(float)fps
67 | readOneFrame:(readOneFrame)readOneFrame
68 | readFinished:(readFinished)readFinished;
69 |
70 |
71 | - (void) readAudioFrameFromTime:(float)startTime
72 | toTime:(float)endTime
73 | readOneFrame:(readOneFrame)readOneFrame
74 | readFinished:(readFinished)readFinished;
75 |
76 | - (void) startVideoRead;
77 |
78 | - (void) stopVideoRead;
79 |
80 | - (void) startAudioRead;
81 |
82 | - (void) stopAudioRead;
83 |
84 | - (void) resetVideoReader;
85 |
86 | - (void) resetAudioReader;
87 |
88 | @end
89 |
90 | #endif /* AVReader_h */
91 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/PictureInPicture/PictureInPictureViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // PictureInPictureViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by adams on 2022/8/17.
6 | // Copyright © 2022 Tencent. All rights reserved.
7 | //
8 |
9 | //Picture-in-picture function (supported by iOS15 and above)
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface PictureInPictureViewController : UIViewController
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/PushCDN/PushCDNAnchorViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // PushCDNAnchorViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by abyyxwang on 2021/4/20.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface PushCDNAnchorViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/PushCDN/PushCDNAudienceViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // PushCDNAudienceViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by abyyxwang on 2021/4/20.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface PushCDNAudienceViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/PushCDN/PushCDNAudienceViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // PushCDNAudienceViewController.m
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by abyyxwang on 2021/4/20.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | /*
10 | CDN Publishing - Audience
11 | TRTC CDN Publishing
12 | This document shows how to integrate the CDN publishing feature.
13 | 1. Set the player delegate: [self.livePlayer setObserver:self];
14 | 2. Set the player container view: [self.livePlayer setRenderView:self.playerView];
15 | 3. Start playback: [self.livePlayer startLivePlay:streamUrl];
16 | Documentation: https://cloud.tencent.com/document/product/647/16827
17 | */
18 |
19 | #import "PushCDNAudienceViewController.h"
20 |
21 | @interface PushCDNAudienceViewController ()
22 |
23 | @property (weak, nonatomic) IBOutlet UILabel *streamIDLabel;
24 | @property (weak, nonatomic) IBOutlet UITextField *streamIDTextField;
25 | @property (weak, nonatomic) IBOutlet UIView *playerView;
26 | @property (weak, nonatomic) IBOutlet UIButton *startPlayButton;
27 |
28 | @property (strong, nonatomic) V2TXLivePlayer *livePlayer;
29 |
30 | @end
31 |
32 | @implementation PushCDNAudienceViewController
33 |
34 | - (V2TXLivePlayer *)livePlayer {
35 | if (!_livePlayer) {
36 | _livePlayer = [[V2TXLivePlayer alloc] init];
37 | }
38 | return _livePlayer;
39 | }
40 |
41 | - (void)viewDidLoad {
42 | [super viewDidLoad];
43 | [self setupDefaultUIConfig];
44 | }
45 |
46 | - (void)setupDefaultUIConfig {
47 | self.streamIDLabel.text = localize(@"TRTC-API-Example.PushCDNAudience.pushStreamAddress");
48 | [self.startPlayButton setTitle:localize(@"TRTC-API-Example.PushCDNAudience.startPlay") forState:UIControlStateNormal];
49 | [self.startPlayButton setTitle:localize(@"TRTC-API-Example.PushCDNAudience.stopPlay") forState:UIControlStateSelected];
50 | [self.startPlayButton setBackgroundColor: UIColor.themeGreenColor];
51 | self.streamIDTextField.placeholder = localize(@"TRTC-API-Example.PushCDNAudience.inputStreamId");
52 | self.streamIDLabel.adjustsFontSizeToFitWidth = YES;
53 | }
54 |
55 | - (void)startPlay {
56 | NSString *streamUrl = [NSString stringWithFormat:@"%@/%@.flv",kCDN_URL,self.streamIDTextField.text];
57 | [self.livePlayer setObserver:self];
58 | [self.livePlayer setRenderView:self.playerView];
59 | V2TXLiveCode ret = [self.livePlayer startLivePlay:streamUrl];
60 | if (ret != 0) {
61 | NSLog(@"play error. code: %ld", ret);
62 | }
63 | }
64 |
65 | - (void)stopPlay {
66 | [self.livePlayer setObserver:nil];
67 | [self.livePlayer setRenderView:nil];
68 | [self.livePlayer stopPlay];
69 | }
70 |
71 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
72 | [super touchesBegan:touches withEvent:event];
73 | if (self.streamIDTextField.isFirstResponder) {
74 | [self.streamIDTextField resignFirstResponder];
75 | }
76 | }
77 |
78 | #pragma mark - IBActions
79 | - (IBAction)onPlayClick:(UIButton *)sender {
80 | sender.selected = !sender.selected;
81 | if (sender.selected) {
82 | [self startPlay];
83 | } else {
84 | [self stopPlay];
85 | }
86 | }
87 |
88 | #pragma mark - V2TXLivePlayerObserver
89 | - (void)onVideoPlaying:(id)player firstPlay:(BOOL)firstPlay extraInfo:(NSDictionary *)extraInfo {
90 | NSLog(@"onVideoPlaying");
91 | }
92 |
93 | - (void)onError:(id)player code:(V2TXLiveCode)code message:(NSString *)msg extraInfo:(NSDictionary *)extraInfo {
94 | NSLog(@"onError: message: %@",msg);
95 | }
96 |
97 |
98 | - (void)dealloc {
99 | [self stopPlay];
100 | }
101 |
102 | @end
103 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/PushCDN/PushCDNSelectRoleViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // PushCDNSelectRoleViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by abyyxwang on 2021/4/20.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface PushCDNSelectRoleViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/RoomPk/RoomPkViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // RoomPkViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by bluedang on 2021/4/22.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface RoomPkViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/SEIMessage/SendAndReceiveSEIMessageViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SendAndReceiveSEIMessageViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by adams on 2021/4/21.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface SendAndReceiveSEIMessageViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/SetAudioEffect/SetAudioEffectViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SetAudioEffectViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by adams on 2021/4/19.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface SetAudioEffectViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/SetAudioQuality/SetAudioQualityViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SetAudioQualityViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by blue on 2021/4/19.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface SetAudioQualityViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/SetBackgroundMusic/SetBGMViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SetBGMViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by adams on 2021/4/20.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface SetBGMViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/SetRenderParams/SetRenderParamsViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SetRenderParamsViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by bluedang on 2021/4/20.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface SetRenderParamsViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/SetVideoQuality/SetVideoQualityViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SetVideoQualityViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by bluedang on 2021/4/19.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface SetVideoQualityViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/SpeedTest/SpeedTestViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SpeedTestViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by bluedang on 2021/4/20.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface SpeedTestViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/SpeedTest/SpeedTestViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // SpeedTestViewController.m
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by bluedang on 2021/4/20.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | /*
10 | Network Speed Testing
11 | TRTC Network Speed Testing
12 | This document shows how to integrate the network speed testing capability.
13 | 1. Test the network: [self.trtcCloud startSpeedTest:SDKAppID userId:_userIdTextField.text userSig:userSig completion:
14 | ^(TRTCSpeedTestResult* result, NSInteger completedCount, NSInteger totalCount){}]
15 | Documentation: https://cloud.tencent.com/document/product/647/32239
16 | */
17 |
18 | #import "SpeedTestViewController.h"
19 |
20 | @interface SpeedTestViewController ()
21 | @property (weak, nonatomic) IBOutlet UILabel *userIdLabel;
22 | @property (weak, nonatomic) IBOutlet UILabel *speedTestLabel;
23 | @property (weak, nonatomic) IBOutlet UITextField *userIdTextField;
24 | @property (weak, nonatomic) IBOutlet UITextView *speedResultTextView;
25 | @property (weak, nonatomic) IBOutlet UIButton *startButton;
26 |
27 | @property (strong, nonatomic) TRTCCloud *trtcCloud;
28 | @property (assign, nonatomic) BOOL isSpeedTesting;
29 | @end
30 |
31 | @implementation SpeedTestViewController
32 |
33 | - (TRTCCloud*)trtcCloud {
34 | if (!_trtcCloud) {
35 | _trtcCloud = [TRTCCloud sharedInstance];
36 | }
37 | return _trtcCloud;
38 | }
39 |
40 | - (void)viewDidLoad {
41 | [super viewDidLoad];
42 |
43 | _isSpeedTesting = false;
44 | self.trtcCloud.delegate = self;
45 | [self setupRandomId];
46 | [self setupDefaultUIConfig];
47 | }
48 |
49 | - (void)setupDefaultUIConfig {
50 | self.title = localize(@"TRTC-API-Example.SpeedTest.title");
51 | _userIdLabel.text = localize(@"TRTC-API-Example.SpeedTest.userId");
52 | _speedTestLabel.text = localize(@"TRTC-API-Example.SpeedTest.speedTestResult");
53 | [_startButton setTitle:localize(@"TRTC-API-Example.SpeedTest.beginTest")
54 | forState:UIControlStateNormal];
55 | _userIdLabel.adjustsFontSizeToFitWidth = true;
56 | _speedTestLabel.adjustsFontSizeToFitWidth = true;
57 | _startButton.adjustsImageWhenHighlighted = true;
58 | }
59 |
60 | - (void)setupRandomId {
61 | _userIdTextField.text = [NSString generateRandomUserId];
62 | }
63 |
64 | - (void)beginSpeedTest {
65 | _isSpeedTesting = true;
66 |
67 | NSString* userSig = [GenerateTestUserSig genTestUserSig:_userIdTextField.text];
68 |
69 | __weak typeof(self) weakSelf = self;
70 | [self.trtcCloud startSpeedTest:SDKAppID userId:_userIdTextField.text userSig:userSig completion:
71 | ^(TRTCSpeedTestResult* result, NSInteger completedCount, NSInteger totalCount){
72 | __strong typeof(weakSelf) strongSelf = weakSelf;
73 | NSString *printResult = [[NSString alloc]
74 | initWithFormat:@"current server:%ld, total server: %ld\n"
75 | "current ip: %@, quality: %ld, upLostRate: %.2f%%\n"
76 | "downLostRate: %.2f%%, rtt: %u\n\n", (long)completedCount,
77 | (long)totalCount, result.ip, result.quality, result.upLostRate * 100,
78 | result.downLostRate * 100, result.rtt];
79 |
80 | strongSelf.speedResultTextView.text = [strongSelf.speedResultTextView.text stringByAppendingString:printResult];
81 |
82 | if (completedCount == totalCount) {
83 | self.isSpeedTesting = false;
84 | [self.startButton setTitle:localize(@"TRTC-API-Example.SpeedTest.completedTest")
85 | forState:UIControlStateNormal];
86 | return;
87 | }
88 |
89 | float percent = completedCount / (float)totalCount;
90 | NSString *strPercent = [[NSString alloc] initWithFormat:@"%.2f %%", percent * 100];
91 | [strongSelf.startButton setTitle:strPercent forState:UIControlStateNormal];
92 | }];
93 | }
94 |
95 | - (IBAction)onStartButtonClick:(UIButton*)sender {
96 | if (_isSpeedTesting) {
97 | return;
98 | }
99 |
100 | if ([_startButton isSelected]) {
101 | [_startButton setTitle:localize(@"TRTC-API-Example.SpeedTest.beginTest")
102 | forState:UIControlStateNormal];
103 | _speedResultTextView.text = @"";
104 | } else {
105 | [self beginSpeedTest];
106 | self.startButton.highlighted = true;
107 | [_startButton setTitle:@"0 %" forState:UIControlStateNormal];
108 | }
109 |
110 | _startButton.selected = !_startButton.selected;
111 | }
112 |
113 | @end
114 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/StringRoomId/StringRoomIdViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // StringRoomIdViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by adams on 2021/4/26.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface StringRoomIdViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/StringRoomId/StringRoomIdViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // StringRoomIdViewController.m
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by adams on 2021/4/26.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | /*
10 | String-type Room ID
11 | The TRTC app supports string-type room IDs.
12 | This document shows how to enable string-type room IDs in your project.
13 | 1. Set a string-type room ID: params.strRoomId = self.roomIDTextField.text
14 | 2. Enter a room: [self.trtcCloud enterRoom:params appScene:TRTCAppSceneLIVE]
15 | Documentation: https://cloud.tencent.com/document/product/647/32258
16 | */
17 |
18 | #import "StringRoomIdViewController.h"
19 | #import "UIViewController+KeyBoard.h"
20 |
21 | @interface StringRoomIdViewController ()
22 | @property (weak, nonatomic) IBOutlet UILabel *roomIdLabel;
23 | @property (weak, nonatomic) IBOutlet UILabel *userIdLabel;
24 |
25 | @property (weak, nonatomic) IBOutlet UIButton *startPushButton;
26 |
27 | @property (weak, nonatomic) IBOutlet UITextField *roomIDTextField;
28 | @property (weak, nonatomic) IBOutlet UITextField *userIDTextField;
29 |
30 | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomConstraint;
31 |
32 | @property (strong, nonatomic) TRTCCloud *trtcCloud;
33 |
34 | @end
35 |
36 | @implementation StringRoomIdViewController
37 |
38 | - (TRTCCloud *)trtcCloud {
39 | if (!_trtcCloud) {
40 | _trtcCloud = [TRTCCloud sharedInstance];
41 | }
42 | return _trtcCloud;
43 | }
44 |
45 | - (void)viewDidLoad {
46 | [super viewDidLoad];
47 | self.trtcCloud.delegate = self;
48 | [self setupDefaultUIConfig];
49 | [self addKeyboardObserver];
50 | }
51 |
52 | - (void)setupDefaultUIConfig {
53 |
54 | self.roomIDTextField.text = @"abc123";
55 | self.userIDTextField.text = [NSString generateRandomUserId];
56 | self.title = localizeReplace(localize(@"TRTC-API-Example.StringRoomId.Title"), self.roomIDTextField.text);
57 |
58 | self.roomIdLabel.text = localize(@"TRTC-API-Example.StringRoomId.roomId");
59 | self.userIdLabel.text = localize(@"TRTC-API-Example.StringRoomId.userId");
60 |
61 | [self.startPushButton setTitle:localize(@"TRTC-API-Example.StringRoomId.start") forState:UIControlStateNormal];
62 | [self.startPushButton setTitle:localize(localize(@"TRTC-API-Example.StringRoomId.stop")) forState:UIControlStateSelected];
63 |
64 | self.startPushButton.titleLabel.adjustsFontSizeToFitWidth = true;
65 | }
66 |
67 | #pragma mark - IBActions
68 | - (IBAction)onStartPushClick:(UIButton *)sender {
69 | sender.selected = !sender.selected;
70 | if (sender.selected) {
71 | [self startPushStream];
72 | } else {
73 | [self stopPushStream];
74 | }
75 | }
76 |
77 | #pragma mark - StartPushStream & StopPushStream
78 | - (void)startPushStream {
79 | [self.trtcCloud startLocalPreview:true view:self.view];
80 |
81 | self.title = localizeReplace(localize(@"TRTC-API-Example.StringRoomId.Title"), self.roomIDTextField.text);
82 | TRTCParams *params = [[TRTCParams alloc] init];
83 | params.sdkAppId = SDKAppID;
84 | params.strRoomId = self.roomIDTextField.text;
85 | params.userId = self.userIDTextField.text;
86 | params.userSig = [GenerateTestUserSig genTestUserSig:self.userIDTextField.text];
87 | params.role = TRTCRoleAnchor;
88 |
89 | [self.trtcCloud enterRoom:params appScene:TRTCAppSceneLIVE];
90 | [self.trtcCloud startLocalAudio:TRTCAudioQualityMusic];
91 |
92 | TRTCVideoEncParam *videoEncParam = [[TRTCVideoEncParam alloc] init];
93 | videoEncParam.videoFps = 24;
94 | videoEncParam.resMode = TRTCVideoResolutionModePortrait;
95 | videoEncParam.videoResolution = TRTCVideoResolution_960_540;
96 | [self.trtcCloud setVideoEncoderParam:videoEncParam];
97 | }
98 |
99 | - (void)stopPushStream {
100 | [self.trtcCloud stopLocalPreview];
101 | [self.trtcCloud stopLocalAudio];
102 | [self.trtcCloud exitRoom];
103 | }
104 |
105 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
106 | [super touchesBegan:touches withEvent:event];
107 | [self.userIDTextField resignFirstResponder];
108 | [self.roomIDTextField resignFirstResponder];
109 | }
110 |
111 | - (void)dealloc {
112 | [self removeKeyboardObserver];
113 | [self.trtcCloud stopLocalPreview];
114 | [self.trtcCloud stopLocalAudio];
115 | [self.trtcCloud exitRoom];
116 | [TRTCCloud destroySharedIntance];
117 | }
118 |
119 |
120 | @end
121 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/SwitchRoom/SwitchRoomViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SwitchRoomViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by adams on 2021/4/20.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface SwitchRoomViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/ThirdBeauty/README-zh_CN.md:
--------------------------------------------------------------------------------
1 | ## 第三方美颜 SDK
2 |
3 | _[English](README.md) | 简体中文_
4 |
5 | 1. 下载依赖的第三方美颜SDK:https://www.faceunity.com/sdk/FaceUnity-SDK-iOS-v7.4.0.zip
6 | 2. 导入SDK
7 | - 下载完成并解压后将库文件夹拖入到工程中,并勾选上 Copy items if needed.
8 | - libCNamaSDK.framework是动态库,需要在General->Framworks,Libraries,and Embedded Content
9 | 中添加依赖关系,并将Embed设置为Embed&Sign,否则会导致运行后因找不到库而崩.
10 | 3. 下载FUTRTCDemo:https://github.com/Faceunity/FUTRTCDemo
11 | 4. 将FUTRTCDemo工程中FaceUnity目录下的以下文件:
12 | - authpack.h
13 | - FUBeautyParam.h
14 | - FUBeautyParam.m
15 | - FUDateHandle.h
16 | - FUDateHandle.m
17 | - FUManager.h
18 | - FUManager.m
19 | 拖入到工程中,并勾选上 Copy items if needed.
20 | 5. 证书添加:authpack.h中的证书key请联系Faceunity获取测试证书并替换到此处(替换后请注释掉或删除此错误警告)。
21 | 6. 取消ThirdBeautyFaceunityViewController.m文件中的以下注释:
22 |
23 | ```
24 | //#import "FUManager.h"
25 | ```
26 |
27 | ```
28 | //@property (strong, nonatomic) FUBeautyParam *beautyParam;
29 | ```
30 |
31 | ```
32 | //- (FUBeautyParam *)beautyParam {
33 | // if (!_beautyParam) {
34 | // _beautyParam = [[FUBeautyParam alloc] init];
35 | // _beautyParam.type = FUDataTypeBeautify;
36 | // _beautyParam.mParam = @"blur_level";
37 | // }
38 | // return _beautyParam;
39 | //}
40 | ```
41 |
42 | ```
43 | // [[FUManager shareManager] loadFilter];
44 | // [FUManager shareManager].isRender = YES;
45 | // [FUManager shareManager].flipx = YES;
46 | // [FUManager shareManager].trackFlipx = YES;
47 | ```
48 |
49 | ```
50 | // self.beautyParam.mValue = sender.value;
51 | // [[FUManager shareManager] filterValueChange:self.beautyParam];
52 | ```
53 |
54 | ```
55 | // [[FUManager shareManager] renderItemsToPixelBuffer:frame.pixelBuffer];
56 | ```
57 |
58 | ```
59 | // [[FUManager shareManager] destoryItems];
60 | ```
61 | 7. Command + R 运行
62 |
63 |
64 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/ThirdBeauty/README.md:
--------------------------------------------------------------------------------
1 | ## Third-Party Beauty SDK
2 |
3 | _[简体中文](README-zh_CN.md) | English_
4 |
5 | 1. Download the dependent third-party beauty SDK: https://www.faceunity.com/sdk/FaceUnity-SDK-iOS-v7.4.0.zip
6 |
7 | 2. Import SDK
8 | - After downloading and decompressing, drag the folder into the project and check "Copy items if needed."
9 | - libCNamaSDK.framework is a dynamic library, which needs to be added to the dependency relationship in General->Framworks, Libraries, and Embedded Content, and set Embed to Embed&Sign, otherwise it will lead to a crash due to the library not being found.
10 |
11 | 3. Download FUTRTCDemo: https://github.com/Faceunity/FUTRTCDemo
12 |
13 | 4. Drag the following files from the FaceUnity directory in the FUTRTCDemo project into your project and check "Copy items if needed":
14 | - authpack.h
15 | - FUBeautyParam.h
16 | - FUBeautyParam.m
17 | - FUDateHandle.h
18 | - FUDateHandle.m
19 | - FUManager.h
20 | - FUManager.m
21 | 5. Add certificate: For the certificate key in authpack.h, please contact Faceunity to obtain a test certificate and replace it here (after replacing, please comment out or delete this error warning).
22 |
23 | 6. Cancel the following comments in the ThirdBeautyFaceunityViewController.m file:
24 | ```
25 | //#import "FUManager.h"
26 | ```
27 |
28 | ```
29 | //@property (strong, nonatomic) FUBeautyParam *beautyParam;
30 | ```
31 |
32 | ```
33 | //- (FUBeautyParam *)beautyParam {
34 | // if (!_beautyParam) {
35 | // _beautyParam = [[FUBeautyParam alloc] init];
36 | // _beautyParam.type = FUDataTypeBeautify;
37 | // _beautyParam.mParam = @"blur_level";
38 | // }
39 | // return _beautyParam;
40 | //}
41 | ```
42 |
43 | ```
44 | // [[FUManager shareManager] loadFilter];
45 | // [FUManager shareManager].isRender = YES;
46 | // [FUManager shareManager].flipx = YES;
47 | // [FUManager shareManager].trackFlipx = YES;
48 | ```
49 |
50 | ```
51 | // self.beautyParam.mValue = sender.value;
52 | // [[FUManager shareManager] filterValueChange:self.beautyParam];
53 | ```
54 |
55 | ```
56 | // [[FUManager shareManager] renderItemsToPixelBuffer:frame.pixelBuffer];
57 | ```
58 |
59 | ```
60 | // [[FUManager shareManager] destoryItems];
61 | ```
62 | 7. Command + R to run
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/ThirdBeauty/ThirdBeautyBytedViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ThirdBeautyBytedViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by adams on 2021/4/22.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface ThirdBeautyBytedViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/ThirdBeauty/ThirdBeautyEntranceViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ThirdBeautyEntranceViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by WesleyLei on 2021/8/17.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface ThirdBeautyEntranceViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/ThirdBeauty/ThirdBeautyEntranceViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ThirdBeautyEntranceViewController.m
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by WesleyLei on 2021/8/17.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import "ThirdBeautyBytedViewController.h"
10 | #import "ThirdBeautyEntranceViewController.h"
11 | #import "ThirdBeautyFaceunityViewController.h"
12 | @interface ThirdBeautyEntranceViewController ()
13 | @property(nonatomic, strong) UIButton *beautyButton;
14 | @property(nonatomic, strong) UIButton *bytedButton;
15 | @property(nonatomic, strong) UIButton *xMagicButton;
16 | @end
17 |
18 | @implementation ThirdBeautyEntranceViewController
19 |
20 | - (void)viewDidLoad {
21 | [super viewDidLoad];
22 | self.title = localize(@"TRTC-API-Example.Home.ThirdBeauty");
23 | [self setupUI];
24 | }
25 |
26 |
27 | - (void)setupUI{
28 | self.beautyButton.frame = CGRectMake(22,
29 | UIScreen.mainScreen.bounds.size.height * 0.5 - 90, UIScreen.mainScreen.bounds.size.width-44, 50);
30 | self.bytedButton.frame = CGRectMake(22,
31 | UIScreen.mainScreen.bounds.size.height * 0.5, UIScreen.mainScreen.bounds.size.width-44, 50);
32 | self.xMagicButton.frame = CGRectMake(22,
33 | UIScreen.mainScreen.bounds.size.height * 0.5 + 90, UIScreen.mainScreen.bounds.size.width-44, 50);
34 | [self.view addSubview:self.beautyButton];
35 | [self.view addSubview:self.bytedButton];
36 | [self.view addSubview:self.xMagicButton];
37 | }
38 |
39 | #pragma mark - Touch Even
40 | - (void)clickBeautyButton {
41 | UIViewController *controller =
42 | [[ThirdBeautyFaceunityViewController alloc] initWithNibName:@"ThirdBeautyFaceunityViewController" bundle:nil];
43 | [self.navigationController pushViewController:controller animated:true];
44 | }
45 |
46 | #pragma mark - Touch Even
47 | - (void)clickBytedButton {
48 | UIViewController *controller =
49 | [[ThirdBeautyBytedViewController alloc] initWithNibName:@"ThirdBeautyBytedViewController"
50 | bundle:nil];
51 | [self.navigationController pushViewController:controller animated:true];
52 | }
53 |
54 | #pragma mark - Touch Even
55 | - (void)clickXmagicButton {
56 | UIViewController *controller =
57 | [[ThirdBeautyBytedViewController alloc] initWithNibName:@"ThirdBeautyTencentEffectViewController"
58 | bundle:nil];
59 | [self.navigationController pushViewController:controller animated:true];
60 | }
61 |
62 | #pragma mark - Gettter
63 | - (UIButton *)beautyButton {
64 | if (!_beautyButton) {
65 | _beautyButton = [UIButton buttonWithType:UIButtonTypeCustom];
66 | _beautyButton.layer.cornerRadius = 5;
67 | [_beautyButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
68 | _beautyButton.backgroundColor = [UIColor greenColor];
69 | [_beautyButton setTitle:localize(@"TRTC-API-Example.ThirdBeauty.faceunity") forState:UIControlStateNormal];
70 | [_beautyButton addTarget:self
71 | action:@selector(clickBeautyButton)
72 | forControlEvents:UIControlEventTouchUpInside];
73 | }
74 | return _beautyButton;
75 | }
76 |
77 | - (UIButton *)bytedButton {
78 | if (!_bytedButton) {
79 | _bytedButton = [UIButton buttonWithType:UIButtonTypeCustom];
80 | [_bytedButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
81 | _bytedButton.layer.cornerRadius = 5;
82 | _bytedButton.backgroundColor = [UIColor greenColor];
83 | [_bytedButton setTitle:localize(@"TRTC-API-Example.ThirdBeauty.bytedance") forState:UIControlStateNormal];
84 | [_bytedButton addTarget:self
85 | action:@selector(clickBytedButton)
86 | forControlEvents:UIControlEventTouchUpInside];
87 | }
88 | return _bytedButton;
89 | }
90 |
91 | - (UIButton *)xMagicButton {
92 | if (!_xMagicButton) {
93 | _xMagicButton = [UIButton buttonWithType:UIButtonTypeCustom];
94 | [_xMagicButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
95 | _xMagicButton.layer.cornerRadius = 5;
96 | _xMagicButton.backgroundColor = [UIColor greenColor];
97 | [_xMagicButton setTitle:localize(@"TRTC-API-Example.ThirdBeauty.xmagic") forState:UIControlStateNormal];
98 | [_xMagicButton addTarget:self
99 | action:@selector(clickXmagicButton)
100 | forControlEvents:UIControlEventTouchUpInside];
101 | }
102 | return _xMagicButton;
103 | }
104 |
105 |
106 |
107 | @end
108 |
109 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/ThirdBeauty/ThirdBeautyEntranceViewController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/ThirdBeauty/ThirdBeautyFaceunityViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ThirdBeautyFaceunityViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by adams on 2021/4/22.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface ThirdBeautyFaceunityViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Advanced/ThirdBeauty/ThirdBeautyTencentEffectViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ThirdBeautyTencentEffectViewController.m
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by summer on 2022/5/11.
6 | // Copyright © 2022 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface ThirdBeautyTencentEffectViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/App/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // TRTCSimpleDemo-OC
4 | //
5 | // Created by dangjiahe on 2021/4/10.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (nonatomic, strong) UIWindow *window;
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/App/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // TRTCSimpleDemo-OC
4 | //
5 | // Created by dangjiahe on 2021/4/10.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 |
24 | #pragma mark - UISceneSession lifecycle
25 |
26 |
27 | - (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options API_AVAILABLE(ios(13.0)){
28 | // Called when a new scene session is being created.
29 | // Use this method to select a configuration to create the new scene with.
30 | return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
31 | }
32 |
33 |
34 | - (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet *)sceneSessions API_AVAILABLE(ios(13.0)){
35 | // Called when the user discards a scene session.
36 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
37 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
38 | }
39 |
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/App/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/App/Extension/NSString+Common.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+Common.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by adams on 2021/4/22.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface NSString (Common)
14 |
15 | + (NSString *)convertToJsonData:(NSDictionary *)dict;
16 |
17 | + (NSString *)generateRandomRoomNumber;
18 |
19 | + (NSString *)generateRandomUserId;
20 |
21 | + (NSString *)generateRandomStreamId;
22 |
23 | @end
24 |
25 | NS_ASSUME_NONNULL_END
26 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/App/Extension/NSString+Common.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+Common.m
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by adams on 2021/4/22.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import "NSString+Common.h"
10 |
11 | @implementation NSString (Common)
12 |
13 | + (NSString *)generateRandomRoomNumber {
14 | return [NSString stringWithFormat:@"%d",arc4random() % (99999999 - 10000000 + 1) + 10000000];
15 | }
16 |
17 | + (NSString *)generateRandomUserId {
18 | return [NSString stringWithFormat:@"%d",arc4random() % (999999 - 100000 + 1) + 100000];
19 | }
20 |
21 | + (NSString *)generateRandomStreamId {
22 | return [NSString stringWithFormat:@"%d", arc4random() % (999999 - 100000 + 1) + 100000];
23 | }
24 |
25 | /// NSDictionary convertTo json
26 | /// @param dict NSDictionary
27 | + (NSString *)convertToJsonData:(NSDictionary *)dict {
28 |
29 | NSError *error;
30 | NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:&error];
31 |
32 | NSString *jsonString;
33 | if (!jsonData) {
34 | NSLog(@"%@",error);
35 |
36 | }else{
37 |
38 | jsonString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
39 |
40 | }
41 |
42 | NSMutableString *mutStr = [NSMutableString stringWithString:jsonString];
43 | NSRange range = {0,jsonString.length};
44 | [mutStr replaceOccurrencesOfString:@" " withString:@"" options:NSLiteralSearch range:range];
45 | NSRange range2 = {0,mutStr.length};
46 | [mutStr replaceOccurrencesOfString:@"\n" withString:@"" options:NSLiteralSearch range:range2];
47 | return mutStr;
48 |
49 | }
50 |
51 | @end
52 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/App/Extension/UIColor+Hex.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIColor+Hex.h
3 | // TRTCSimpleDemo-OC
4 | //
5 | // Created by adams on 2021/4/14.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface UIColor (Hex)
14 |
15 | + (UIColor *)hexColor:(NSString *)hexString;
16 |
17 | + (UIColor *)themeGreenColor;
18 |
19 | + (UIColor *)themeGrayColor;
20 |
21 | - (UIImage *)trans2Image:(CGSize)imageSize;
22 |
23 | @end
24 |
25 | NS_ASSUME_NONNULL_END
26 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/App/Extension/UIColor+Hex.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIColor+Hex.m
3 | // TRTCSimpleDemo-OC
4 | //
5 | // Created by adams on 2021/4/14.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import "UIColor+Hex.h"
10 |
11 | @implementation UIColor (Hex)
12 | + (UIColor *)hexColor:(NSString *)hexString {
13 | NSString *colorString = [[hexString stringByReplacingOccurrencesOfString: @"#" withString: @""] uppercaseString];
14 | CGFloat alpha, red, blue, green;
15 | switch ([colorString length]) {
16 | case 3: // #RGB
17 | alpha = 1.0f;
18 | red = [self colorComponentFrom: colorString start: 0 length: 1];
19 | green = [self colorComponentFrom: colorString start: 1 length: 1];
20 | blue = [self colorComponentFrom: colorString start: 2 length: 1];
21 | break;
22 | case 4: // #ARGB
23 | alpha = [self colorComponentFrom: colorString start: 0 length: 1];
24 | red = [self colorComponentFrom: colorString start: 1 length: 1];
25 | green = [self colorComponentFrom: colorString start: 2 length: 1];
26 | blue = [self colorComponentFrom: colorString start: 3 length: 1];
27 | break;
28 | case 6: // #RRGGBB
29 | alpha = 1.0f;
30 | red = [self colorComponentFrom: colorString start: 0 length: 2];
31 | green = [self colorComponentFrom: colorString start: 2 length: 2];
32 | blue = [self colorComponentFrom: colorString start: 4 length: 2];
33 | break;
34 | case 8: // #AARRGGBB
35 | alpha = [self colorComponentFrom: colorString start: 0 length: 2];
36 | red = [self colorComponentFrom: colorString start: 2 length: 2];
37 | green = [self colorComponentFrom: colorString start: 4 length: 2];
38 | blue = [self colorComponentFrom: colorString start: 6 length: 2];
39 | break;
40 | default:
41 | blue=0;
42 | green=0;
43 | red=0;
44 | alpha=0;
45 | break;
46 | }
47 | return [UIColor colorWithRed: red green: green blue: blue alpha: alpha];
48 | }
49 |
50 | + (CGFloat)colorComponentFrom:(NSString *)string start:(NSUInteger)start length:(NSUInteger)length {
51 | NSString *substring = [string substringWithRange: NSMakeRange(start, length)];
52 | NSString *fullHex = length == 2 ? substring : [NSString stringWithFormat: @"%@%@", substring, substring];
53 | unsigned hexComponent;
54 | [[NSScanner scannerWithString: fullHex] scanHexInt: &hexComponent];
55 | return hexComponent / 255.0;
56 | }
57 |
58 | + (UIColor *)themeGreenColor {
59 | return [UIColor hexColor:@"#34c759"];
60 | }
61 |
62 | + (UIColor *)themeGrayColor {
63 | return [[UIColor hexColor:@"#999999"] colorWithAlphaComponent:0.85];
64 | }
65 |
66 | - (UIImage *)trans2Image:(CGSize)imageSize {
67 | CGRect rect = CGRectMake(0, 0, imageSize.width, imageSize.height);
68 | UIGraphicsBeginImageContext(rect.size);
69 | CGContextRef context = UIGraphicsGetCurrentContext();
70 | CGContextSetFillColorWithColor(context, self.CGColor);
71 | CGContextFillRect(context, rect);
72 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
73 | UIGraphicsEndImageContext();
74 | return image ?: [[UIImage alloc] init];
75 | }
76 | @end
77 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/App/Extension/UIViewController+AlertViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIViewController+AlertViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by adams on 2021/4/15.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface UIViewController (AlertViewController)
14 | - (void)showAlertViewController:(nullable NSString *)title
15 | message:(nullable NSString *)message
16 | handler:(void (^ __nullable)(UIAlertAction *action))handler;
17 |
18 | - (void)requestPhotoAuthorization:(void(^)(void))handler;
19 |
20 | @end
21 |
22 | NS_ASSUME_NONNULL_END
23 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/App/Extension/UIViewController+AlertViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIViewController+AlertViewController.m
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by adams on 2021/4/15.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 |
8 | #import "UIViewController+AlertViewController.h"
9 | #import
10 | @implementation UIViewController (AlertViewController)
11 |
12 | - (void)showAlertViewController:(NSString *)title message:(NSString *)message handler:(void (^ __nullable)(UIAlertAction *action))handler {
13 | UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
14 | UIAlertAction *alertAction = [UIAlertAction actionWithTitle:localize(@"TRTC-API-Example.AlertViewController.determine") style:UIAlertActionStyleDefault handler:handler];
15 | [alertVC addAction:alertAction];
16 | [self presentViewController:alertVC animated:true completion:nil];
17 | }
18 |
19 | - (void)requestPhotoAuthorization:(void(^)(void))handler {
20 | if (@available(iOS 14, *)) {
21 | PHAccessLevel level = PHAccessLevelReadWrite;
22 | [PHPhotoLibrary requestAuthorizationForAccessLevel:level handler:^(PHAuthorizationStatus status) {
23 | switch (status) {
24 | case PHAuthorizationStatusLimited:
25 | handler();
26 | break;
27 | case PHAuthorizationStatusAuthorized:
28 | handler();
29 | break;
30 | default:
31 | break;
32 | }
33 | }];
34 | } else {
35 | [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
36 | switch (status) {
37 | case PHAuthorizationStatusAuthorized:
38 | handler();
39 | break;
40 | default:
41 | break;
42 | }
43 | }];
44 | }
45 | }
46 |
47 | @end
48 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/App/Home/HomeTableViewCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // HomeTableViewCell.h
3 | // TRTCSimpleDemo-OC
4 | //
5 | // Created by adams on 2021/4/14.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 | static NSString *gHomeTableViewCellReuseIdentify = @"HomeTableViewCell";
13 | @interface HomeTableViewCell : UITableViewCell
14 | - (void)setHomeDictionary:(NSDictionary *)homeDic;
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/App/Home/HomeTableViewCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // HomeTableViewCell.m
3 | // TRTCSimpleDemo-OC
4 | //
5 | // Created by adams on 2021/4/14.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import "HomeTableViewCell.h"
10 | @interface HomeTableViewCell()
11 | @property (weak, nonatomic) IBOutlet UILabel *titleLabel;
12 | @property (weak, nonatomic) IBOutlet UILabel *descLabel;
13 | @property (weak, nonatomic) IBOutlet UIView *containerView;
14 | @property (weak, nonatomic) IBOutlet UILabel *centerTitleLabel;
15 | @property (nonatomic, strong) CAShapeLayer *maskLayer;
16 | @end
17 | @implementation HomeTableViewCell
18 |
19 | - (CAShapeLayer *)maskLayer {
20 | if (!_maskLayer) {
21 | UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.containerView.bounds
22 | byRoundingCorners: UIRectCornerTopLeft |
23 | UIRectCornerTopRight |
24 | UIRectCornerBottomLeft |
25 | UIRectCornerBottomRight
26 | cornerRadii:CGSizeMake(8, 8)];
27 | _maskLayer = [[CAShapeLayer alloc] init];
28 | _maskLayer.frame = self.containerView.bounds;
29 | _maskLayer.path = maskPath.CGPath;
30 | }
31 | return _maskLayer;
32 | }
33 |
34 | - (void)awakeFromNib {
35 | [super awakeFromNib];
36 | self.titleLabel.adjustsFontSizeToFitWidth = true;
37 | self.descLabel.adjustsFontSizeToFitWidth = true;
38 | self.centerTitleLabel.adjustsFontSizeToFitWidth = true;
39 | }
40 |
41 | -(void)drawRect:(CGRect)rect {
42 | [super drawRect:rect];
43 | self.containerView.layer.mask = self.maskLayer;
44 | }
45 |
46 | - (void)setHomeDictionary:(NSDictionary *)homeDic {
47 | if ([[homeDic objectForKey:@"desc"] isEqualToString:@""]) {
48 | [self.centerTitleLabel setHidden: false];
49 | [self.descLabel setHidden: true];
50 | [self.titleLabel setHidden: true];
51 | self.centerTitleLabel.text = [homeDic objectForKey:@"title"];
52 | } else {
53 | [self.centerTitleLabel setHidden: true];
54 | [self.descLabel setHidden: false];
55 | [self.titleLabel setHidden: false];
56 | self.titleLabel.text = [homeDic objectForKey:@"title"];
57 | self.descLabel.text = [homeDic objectForKey:@"desc"];
58 | }
59 | }
60 |
61 | @end
62 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/App/Home/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // TRTCSimpleDemo-OC
4 | //
5 | // Created by dangjiahe on 2021/4/10.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/App/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 3963
21 | LSRequiresIPhoneOS
22 |
23 | NSAppTransportSecurity
24 |
25 | NSAllowsArbitraryLoads
26 |
27 |
28 | NSCameraUsageDescription
29 | 需要访问你的相机权限,开启后录制的视频才会有画面
30 | NSMicrophoneUsageDescription
31 | 需要访问你的麦克风权限,开启后录制的视频才会有声音
32 | NSPhotoLibraryAddUsageDescription
33 | 需要访问你的相册权限,开启后才能保存编辑的文件
34 | NSPhotoLibraryUsageDescription
35 | 需要访问你的相册权限,开启后才能编辑视频文件
36 | UIApplicationSceneManifest
37 |
38 | UIApplicationSupportsMultipleScenes
39 |
40 | UISceneConfigurations
41 |
42 | UIWindowSceneSessionRoleApplication
43 |
44 |
45 | UISceneConfigurationName
46 | Default Configuration
47 | UISceneDelegateClassName
48 | SceneDelegate
49 | UISceneStoryboardFile
50 | Main
51 |
52 |
53 |
54 |
55 | UIApplicationSupportsIndirectInputEvents
56 |
57 | UIBackgroundModes
58 |
59 | audio
60 |
61 | UILaunchStoryboardName
62 | LaunchScreen
63 | UIMainStoryboardFile
64 | Main
65 | UIRequiredDeviceCapabilities
66 |
67 | armv7
68 |
69 | UISupportedInterfaceOrientations
70 |
71 | UIInterfaceOrientationPortrait
72 |
73 | UISupportedInterfaceOrientations~ipad
74 |
75 | UIInterfaceOrientationPortrait
76 | UIInterfaceOrientationPortraitUpsideDown
77 | UIInterfaceOrientationLandscapeLeft
78 | UIInterfaceOrientationLandscapeRight
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/App/PCH/TRTC-API-Example-OC-PrefixHeader.pch:
--------------------------------------------------------------------------------
1 | //
2 | // TRTC-API-Example-OC-PrefixHeader.pch
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by adams on 2021/4/14.
6 | //
7 |
8 | #ifndef TRTC_API_Example_OC_PrefixHeader_pch
9 | #define TRTC_API_Example_OC_PrefixHeader_pch
10 |
11 | #import "AppLocalized.h"
12 | #import "UIColor+Hex.h"
13 | #import "GenerateTestUserSig.h"
14 | #import "NSString+Common.h"
15 | #import "UIViewController+AlertViewController.h"
16 | @import TXLiteAVSDK_TRTC;
17 |
18 |
19 | #endif /* TRTC_API_Example_OC_PrefixHeader_pch */
20 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/App/SceneDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.h
3 | // TRTCSimpleDemo-OC
4 | //
5 | // Created by dangjiahe on 2021/4/10.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface SceneDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow * window;
14 |
15 | @end
16 |
17 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/App/SceneDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.m
3 | // TRTCSimpleDemo-OC
4 | //
5 | // Created by dangjiahe on 2021/4/10.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import "SceneDelegate.h"
10 |
11 | @interface SceneDelegate ()
12 |
13 | @end
14 |
15 | @implementation SceneDelegate
16 |
17 |
18 | - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
19 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
20 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
21 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
22 | }
23 |
24 |
25 | - (void)sceneDidDisconnect:(UIScene *)scene {
26 | // Called as the scene is being released by the system.
27 | // This occurs shortly after the scene enters the background, or when its session is discarded.
28 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
29 | // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
30 | }
31 |
32 |
33 | - (void)sceneDidBecomeActive:(UIScene *)scene {
34 | // Called when the scene has moved from an inactive state to an active state.
35 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
36 | }
37 |
38 |
39 | - (void)sceneWillResignActive:(UIScene *)scene {
40 | // Called when the scene will move from an active state to an inactive state.
41 | // This may occur due to temporary interruptions (ex. an incoming phone call).
42 | }
43 |
44 |
45 | - (void)sceneWillEnterForeground:(UIScene *)scene {
46 | // Called as the scene transitions from the background to the foreground.
47 | // Use this method to undo the changes made on entering the background.
48 | }
49 |
50 |
51 | - (void)sceneDidEnterBackground:(UIScene *)scene {
52 | // Called as the scene transitions from the foreground to the background.
53 | // Use this method to save data, release shared resources, and store enough scene-specific state information
54 | // to restore the scene back to its current state.
55 | }
56 |
57 |
58 | @end
59 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/App/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // TRTCSimpleDemo-OC
4 | //
5 | // Created by dangjiahe on 2021/4/10.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | NSString * appDelegateClassName;
14 | @autoreleasepool {
15 | // Setup code that might create autoreleased objects goes here.
16 | appDelegateClassName = NSStringFromClass([AppDelegate class]);
17 | }
18 | return UIApplicationMain(argc, argv, nil, appDelegateClassName);
19 | }
20 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Basic/AudioCall/AudioCallingEnterViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // AudioCallingEnterViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by bluedang on 2021/4/14.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | //MARK: Voice call example - room entry
14 | @interface AudioCallingEnterViewController : UIViewController
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Basic/AudioCall/AudioCallingEnterViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // AudioCallingEnterViewController.m
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by bluedang on 2021/4/14.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 |
10 | #import "AudioCallingEnterViewController.h"
11 | #import "AudioCallingViewController.h"
12 |
13 | @interface AudioCallingEnterViewController ()
14 | @property (weak, nonatomic) IBOutlet UITextField *userIdTextField;
15 | @property (weak, nonatomic) IBOutlet UITextField *roomIdTextField;
16 | @property (weak, nonatomic) IBOutlet UILabel *inputRoomLabel;
17 | @property (weak, nonatomic) IBOutlet UILabel *inputUserLabel;
18 | @property (weak, nonatomic) IBOutlet UIButton *startButton;
19 | @end
20 |
21 | @implementation AudioCallingEnterViewController
22 |
23 | - (void)viewDidLoad {
24 | [super viewDidLoad];
25 |
26 | [self setupDefaultUIConfig];
27 | [self setupRandomId];
28 | }
29 |
30 | - (void)setupDefaultUIConfig {
31 | self.title = localize(@"TRTC-API-Example.AudioCallingEnter.Title");
32 | _inputRoomLabel.text = localize(@"TRTC-API-Example.AudioCallingEnter.EnterRoomNumber");
33 | _inputUserLabel.text = localize(@"TRTC-API-Example.AudioCallingEnter.EnterUserName");
34 | [_startButton setTitle:localize(@"TRTC-API-Example.AudioCallingEnter.EnterRoom") forState:UIControlStateNormal];
35 | }
36 |
37 | - (void)setupRandomId {
38 | _roomIdTextField.text = @"1356732";
39 | _userIdTextField.text = [NSString generateRandomUserId];
40 | }
41 |
42 | - (IBAction)onStartClick:(id)sender {
43 | AudioCallingViewController *audioCallingVC = [[AudioCallingViewController alloc] initWithRoomId:[_roomIdTextField.text intValue]
44 | userId:_userIdTextField.text];
45 |
46 | [self.navigationController pushViewController:audioCallingVC animated:YES];
47 | }
48 |
49 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
50 | [super touchesBegan:touches withEvent:event];
51 | [self.view endEditing:true];
52 | }
53 |
54 | @end
55 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Basic/AudioCall/AudioCallingViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // AudioCallingViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by bluedang on 2021/4/14.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | //MARK: Voice call example - call interface
14 | @interface AudioCallingViewController : UIViewController
15 | - (instancetype)initWithRoomId:(UInt32)roomId userId:(NSString *)userId;
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Basic/Live/LiveAnchorViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // LiveAnchorViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by adams on 2021/4/14.
6 | // Copyright (c) adams Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface LiveAnchorViewController : UIViewController
14 |
15 | - (instancetype)initWithRoomId:(UInt32)roomId userId:(NSString *)userId;
16 |
17 | @end
18 |
19 | NS_ASSUME_NONNULL_END
20 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Basic/Live/LiveAudienceViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // LiveAudienceViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by adams on 2021/4/14.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface LiveAudienceViewController : UIViewController
14 |
15 | - (instancetype)initWithRoomId:(UInt32)roomId userId:(NSString *)userId;
16 |
17 | @end
18 |
19 | NS_ASSUME_NONNULL_END
20 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Basic/Live/LiveAudienceViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // LiveAudienceViewController.m
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by adams on 2021/4/14.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | /*
10 | Interactive Live Video Streaming - Audience
11 | The TRTC app supports interactive live video streaming.
12 | This document shows how to integrate the interactive live video streaming feature.
13 | 1. Enter a room: [self.trtcCloud enterRoom:params appScene:TRTCAppSceneLIVE]
14 | 2. Display the video of a remote user: [self.trtcCloud startRemoteView:userId streamType:TRTCVideoStreamTypeBig view:self.view]
15 | 3. Mute a remote user: [self.trtcCloud muteRemoteAudio:userId mute:sender.selected]
16 | Documentation: https://cloud.tencent.com/document/product/647/43181
17 | */
18 |
19 | #import "LiveAudienceViewController.h"
20 | static const NSInteger maxRemoteUserNum = 6;
21 |
22 | @interface LiveAudienceViewController ()
23 | @property (weak, nonatomic) IBOutlet UILabel *audienceLabel;
24 | @property (weak, nonatomic) IBOutlet UIButton *muteButton;
25 | @property (nonatomic, strong) TRTCCloud *trtcCloud;
26 | @property (nonatomic, strong) NSMutableOrderedSet *anchorUserIdSet;
27 | @end
28 |
29 | @implementation LiveAudienceViewController
30 |
31 | - (NSMutableOrderedSet *)anchorUserIdSet {
32 | if (!_anchorUserIdSet) {
33 | _anchorUserIdSet = [[NSMutableOrderedSet alloc] initWithCapacity:maxRemoteUserNum];
34 | }
35 | return _anchorUserIdSet;
36 | }
37 |
38 | - (TRTCCloud *)trtcCloud {
39 | if (!_trtcCloud) {
40 | _trtcCloud = [TRTCCloud sharedInstance];
41 | }
42 | return _trtcCloud;
43 | }
44 |
45 | - (instancetype)initWithRoomId:(UInt32)roomId userId:(NSString *)userId {
46 | self = [super initWithNibName:NSStringFromClass([self class]) bundle:nil];
47 | if (self) {
48 | [self onEnterRoom:roomId userId:userId];
49 | }
50 | return self;
51 | }
52 |
53 | - (void)viewDidLoad {
54 | [super viewDidLoad];
55 | [self setupDefaultUIConfig];
56 | }
57 |
58 | - (void)setupDefaultUIConfig {
59 | self.audienceLabel.text = localize(@"TRTC-API-Example.LiveAudience.Operating");
60 | [self.muteButton setTitle:localize(@"TRTC-API-Example.LiveAudience.mute") forState:UIControlStateNormal];
61 | [self.muteButton setTitle:localize(@"TRTC-API-Example.LiveAudience.muteoff") forState:UIControlStateSelected];
62 | self.audienceLabel.adjustsFontSizeToFitWidth = true;
63 | self.muteButton.titleLabel.adjustsFontSizeToFitWidth = true;
64 | }
65 |
66 | - (void)onEnterRoom:(UInt32)roomId userId:(NSString *)userId {
67 | TRTCParams *params = [[TRTCParams alloc] init];
68 | params.sdkAppId = SDKAppID;
69 | params.roomId = roomId;
70 | params.userId = userId;
71 | params.userSig = [GenerateTestUserSig genTestUserSig:userId];
72 | params.role = TRTCRoleAudience;
73 | self.trtcCloud.delegate = self;
74 | [self.trtcCloud enterRoom:params appScene:TRTCAppSceneLIVE];
75 | }
76 |
77 | #pragma mark - IBActions
78 | - (IBAction)onMuteClick:(UIButton *)sender {
79 | sender.selected = !sender.selected;
80 | NSInteger index = 0;
81 | for (NSString* userId in self.anchorUserIdSet) {
82 | if (index >= maxRemoteUserNum) { return; }
83 | [self.trtcCloud muteRemoteAudio:userId mute:sender.selected];
84 | }
85 | }
86 |
87 | #pragma mark - TRTCCloudDelegate
88 | - (void)onUserVideoAvailable:(NSString *)userId available:(BOOL)available {
89 | NSInteger index = [self.anchorUserIdSet indexOfObject:userId];
90 | if (available) {
91 | [self.trtcCloud startRemoteView:userId streamType:TRTCVideoStreamTypeBig view:self.view];
92 | if (index != NSNotFound) { return; }
93 | [self.anchorUserIdSet addObject:userId];
94 | } else {
95 | [self.trtcCloud stopRemoteView:userId streamType:TRTCVideoStreamTypeBig];
96 | if (index) {
97 | [self.anchorUserIdSet removeObject:userId];
98 | }
99 | }
100 | }
101 |
102 | - (void)dealloc
103 | {
104 | [self.trtcCloud stopLocalPreview];
105 | [self.trtcCloud stopLocalAudio];
106 | [self.trtcCloud exitRoom];
107 | [TRTCCloud destroySharedIntance];
108 | }
109 |
110 | @end
111 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Basic/Live/LiveEnterViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // LiveEnterViewController.h
3 | // TRTCSimpleDemo-OC
4 | //
5 | // Created by adams on 2021/4/14.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface LiveEnterViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Basic/Live/LiveEnterViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // LiveEnterViewController.m
3 | // TRTCSimpleDemo-OC
4 | //
5 | // Created by adams on 2021/4/14.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import "LiveEnterViewController.h"
10 | #import "LiveAnchorViewController.h"
11 | #import "LiveAudienceViewController.h"
12 |
13 | typedef NS_ENUM(NSUInteger, UserType) {
14 | Anchor,
15 | Audience,
16 | };
17 |
18 | @interface LiveEnterViewController ()
19 | @property (weak, nonatomic) IBOutlet UILabel *enterRoomLabel;
20 | @property (weak, nonatomic) IBOutlet UITextField *enterRoomTextField;
21 | @property (weak, nonatomic) IBOutlet UILabel *enterUserNameLabel;
22 | @property (weak, nonatomic) IBOutlet UITextField *enterUserNameTextField;
23 | @property (weak, nonatomic) IBOutlet UILabel *userIdentifyLabel;
24 | @property (weak, nonatomic) IBOutlet UIButton *anchorButton;
25 | @property (weak, nonatomic) IBOutlet UIButton *audienceButton;
26 | @property (weak, nonatomic) IBOutlet UIButton *enterRoomButton;
27 |
28 | @property (nonatomic, assign) UserType userType;
29 |
30 | @end
31 |
32 | @implementation LiveEnterViewController
33 |
34 | - (void)viewDidLoad {
35 | [super viewDidLoad];
36 | self.title = localize(@"TRTC-API-Example.Live.Title");
37 | [self setupDefaultUIConfig];
38 | }
39 |
40 | - (void)setupDefaultUIConfig {
41 | self.enterRoomLabel.text = localize(@"TRTC-API-Example.Live.EnterRoomNumber");
42 | self.enterUserNameLabel.text = localize(@"TRTC-API-Example.Live.EnterUserName");
43 | self.userIdentifyLabel.text = localize(@"TRTC-API-Example.Live.ChooseUserIdentify");
44 | [self.anchorButton setTitle:localize(@"TRTC-API-Example.Live.Anchor") forState:UIControlStateNormal];
45 | [self.audienceButton setTitle:localize(@"TRTC-API-Example.Live.Audience") forState:UIControlStateNormal];
46 | [self.enterRoomButton setTitle:localize(@"TRTC-API-Example.Live.EnterRoom") forState:UIControlStateNormal];
47 |
48 | self.enterRoomTextField.text = @"1256732";
49 | self.enterUserNameTextField.text = @"324532";
50 | self.audienceButton.titleLabel.adjustsFontSizeToFitWidth = YES;
51 | self.userType = Anchor;
52 | }
53 |
54 | - (void)setUserType:(UserType)userType {
55 | _userType = userType;
56 | switch (userType) {
57 | case Audience:
58 | [self.audienceButton setBackgroundColor:[UIColor themeGreenColor]];
59 | [self.anchorButton setBackgroundColor:[UIColor themeGrayColor]];
60 | break;
61 | case Anchor:
62 | [self.anchorButton setBackgroundColor:[UIColor themeGreenColor]];
63 | [self.audienceButton setBackgroundColor:[UIColor themeGrayColor]];
64 | break;
65 |
66 | default:
67 | break;
68 | }
69 | }
70 |
71 | #pragma mark - IBActions
72 | - (IBAction)onAudienceClick:(UIButton *)sender {
73 | self.userType = Audience;
74 | }
75 |
76 | - (IBAction)onAnchorClick:(UIButton *)sender {
77 | self.userType = Anchor;
78 | }
79 |
80 | - (IBAction)onEnterRoomButtonClick:(id)sender {
81 | if (self.enterRoomTextField.text.length == 0 || self.enterUserNameTextField.text == 0) {
82 | [self showAlertViewController:localize(@"TRTC-API-Example.AlertViewController.ponit") message:localize(@"TRTC-API-Example.Live.tips") handler:nil];
83 | return;
84 | }
85 | UInt32 roomId = [self.enterRoomTextField.text intValue];
86 | NSString *userId = self.enterUserNameTextField.text;
87 | switch (self.userType) {
88 | case Anchor:
89 | {
90 | LiveAnchorViewController *anchorVC =
91 | [[LiveAnchorViewController alloc] initWithRoomId:roomId userId:userId];
92 | anchorVC.title = localizeReplace(localize(@"TRTC-API-Example.LiveAnchor.Title"), self.enterRoomTextField.text);
93 | [self.navigationController pushViewController:anchorVC animated:YES];
94 | }
95 | break;
96 | case Audience:
97 | {
98 | LiveAudienceViewController *audienceVC =
99 | [[LiveAudienceViewController alloc] initWithRoomId:roomId userId:userId];
100 | audienceVC.title = localizeReplace(localize(@"TRTC-API-Example.LiveAudience.Title"), self.enterRoomTextField.text);
101 | [self.navigationController pushViewController:audienceVC animated:YES];
102 | }
103 | break;
104 |
105 | default:
106 | break;
107 | }
108 | }
109 |
110 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
111 | [super touchesBegan:touches withEvent:event];
112 | [self.enterRoomTextField resignFirstResponder];
113 | [self.enterUserNameTextField resignFirstResponder];
114 | }
115 |
116 | @end
117 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Basic/ScreenShare/ScreenAnchorViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ScreenAnchorViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by bluedang on 2021/4/15.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | //MARK: Screen recording live broadcast example - anchor interface
14 | @interface ScreenAnchorViewController : UIViewController
15 | @property (assign, nonatomic) UInt32 roomId;
16 | @property (strong, nonatomic) NSString* userId;
17 | @end
18 |
19 | NS_ASSUME_NONNULL_END
20 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Basic/ScreenShare/ScreenAudienceViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ScreenAudienceViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by bluedang on 2021/4/15.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | //MARK: Screen recording live broadcast example - audience interface
14 | @interface ScreenAudienceViewController : UIViewController
15 | @property (assign, nonatomic) UInt32 roomId;
16 | @property (strong, nonatomic) NSString* userId;
17 | @end
18 |
19 | NS_ASSUME_NONNULL_END
20 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Basic/ScreenShare/ScreenAudienceViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ScreenAudienceViewController.m
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by bluedang on 2021/4/15.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 |
10 | #import "ScreenAudienceViewController.h"
11 |
12 | @interface ScreenAudienceViewController ()
13 | @property (weak, nonatomic) IBOutlet UIView *remoteView;
14 | @property (strong, nonatomic) TRTCCloud *trtcCloud;
15 | @end
16 |
17 | @implementation ScreenAudienceViewController
18 |
19 |
20 | - (TRTCCloud*)trtcCloud {
21 | if (!_trtcCloud) {
22 | _trtcCloud = [TRTCCloud sharedInstance];
23 | }
24 | return _trtcCloud;
25 | }
26 |
27 | - (void)viewDidLoad {
28 | [super viewDidLoad];
29 | self.title = [localize(@"TRTC-API-Example.ScreenAudience.Title")
30 | stringByAppendingString: [@(_roomId) stringValue]];
31 |
32 | self.trtcCloud.delegate = self;
33 |
34 | TRTCParams *params = [TRTCParams new];
35 | params.sdkAppId = SDKAppID;
36 | params.roomId = _roomId;
37 | params.userId = _userId;
38 | params.role = TRTCRoleAudience;
39 | params.userSig = [GenerateTestUserSig genTestUserSig:params.userId];
40 |
41 | [self.trtcCloud startLocalAudio:TRTCAudioQualityMusic];
42 | [self.trtcCloud enterRoom:params appScene:TRTCAppSceneVideoCall];
43 | }
44 |
45 | - (void)dealloc {
46 | [self.trtcCloud exitRoom];
47 | [TRTCCloud destroySharedIntance];
48 | }
49 |
50 | #pragma mark - TRTCCloud Delegate
51 |
52 | - (void)onUserVideoAvailable:(NSString *)userId available:(BOOL)available {
53 | if (available) {
54 | [_remoteView setHidden:false];
55 | [_trtcCloud startRemoteView:userId streamType:TRTCVideoStreamTypeBig
56 | view:_remoteView];
57 | } else {
58 | [_remoteView setHidden:true];
59 | }
60 | }
61 |
62 | @end
63 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Basic/ScreenShare/ScreenAudienceViewController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Basic/ScreenShare/ScreenEntranceViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ScreenEntranceViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by bluedang on 2021/4/15.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | //MARK: Screen recording live broadcast example - room entry
14 | @interface ScreenEntranceViewController : UIViewController
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Basic/ScreenShare/ScreenEntranceViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ScreenEntranceViewController.m
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by bluedang on 2021/4/15.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import "ScreenEntranceViewController.h"
10 | #import "ScreenAnchorViewController.h"
11 | #import "ScreenAudienceViewController.h"
12 | #import "UIColor+Hex.h"
13 |
14 | @interface ScreenEntranceViewController ()
15 |
16 | @property (weak, nonatomic) IBOutlet UILabel *inputRoomLabel;
17 | @property (weak, nonatomic) IBOutlet UILabel *inputUserLabel;
18 | @property (weak, nonatomic) IBOutlet UILabel *roleLabel;
19 | @property (weak, nonatomic) IBOutlet UITextField *roomIdTextField;
20 | @property (weak, nonatomic) IBOutlet UITextField *userIdTextField;
21 | @property (weak, nonatomic) IBOutlet UIButton *anchorButton;
22 | @property (weak, nonatomic) IBOutlet UIButton *audienceButton;
23 | @property (weak, nonatomic) IBOutlet UIButton *enterRoomButton;
24 | @property (assign, nonatomic) BOOL isAnchorChoose;
25 | @end
26 |
27 | @implementation ScreenEntranceViewController
28 |
29 | - (void)viewDidLoad {
30 | [super viewDidLoad];
31 |
32 | [self setupDefaultUIConfig];
33 | [self setupRandomId];
34 |
35 | self.isAnchorChoose = true;
36 | }
37 |
38 | - (void)setupDefaultUIConfig {
39 | self.title = localize(@"TRTC-API-Example.ScreenEntrance.Title");
40 | _inputRoomLabel.text = localize(@"TRTC-API-Example.ScreenEntrance.EnterRoomNumber");
41 | _inputUserLabel.text = localize(@"TRTC-API-Example.ScreenEntrance.EnterUserName");
42 | _roleLabel.text = localize(@"TRTC-API-Example.ScreenEntrance.EnterRole");
43 | [_anchorButton setTitle:localize(@"TRTC-API-Example.ScreenEntrance.Anchor") forState:UIControlStateNormal];
44 | [_audienceButton setTitle:localize(@"TRTC-API-Example.ScreenEntrance.Audience") forState:UIControlStateNormal];
45 | [_enterRoomButton setTitle:localize(@"TRTC-API-Example.ScreenEntrance.EnterRoom") forState:UIControlStateNormal];
46 | _inputRoomLabel.adjustsFontSizeToFitWidth = true;
47 | _inputUserLabel.adjustsFontSizeToFitWidth = true;
48 | _roleLabel.adjustsFontSizeToFitWidth = true;
49 | _anchorButton.titleLabel.adjustsFontSizeToFitWidth = true;
50 | _audienceButton.titleLabel.adjustsFontSizeToFitWidth = true;
51 | _enterRoomButton.titleLabel.adjustsFontSizeToFitWidth = true;
52 | }
53 |
54 | - (void)setupRandomId {
55 | _roomIdTextField.text = @"1356732";
56 | _userIdTextField.text = [NSString generateRandomUserId];
57 | }
58 |
59 | - (IBAction)onAnchorClick:(UIButton*)sender {
60 | _isAnchorChoose = true;
61 | _anchorButton.backgroundColor = [UIColor themeGreenColor];
62 | _audienceButton.backgroundColor = [UIColor hexColor:@"#d8d8d8"];
63 | }
64 |
65 | - (IBAction)onAudienceClick:(UIButton *)sender {
66 | _isAnchorChoose = false;
67 | _anchorButton.backgroundColor = [UIColor hexColor:@"#d8d8d8"];
68 | _audienceButton.backgroundColor = [UIColor themeGreenColor];
69 | }
70 |
71 | - (IBAction)onEnterRoomClick:(UIButton *)sender {
72 | if (_isAnchorChoose) {
73 | if (@available(iOS 13.0, *)) {
74 | ScreenAnchorViewController *anchroVC = [[ScreenAnchorViewController
75 | alloc] initWithNibName:@"ScreenAnchorViewController" bundle:nil];
76 | anchroVC.roomId = [_roomIdTextField.text intValue];
77 | anchroVC.userId = _userIdTextField.text;
78 | [self.navigationController pushViewController:anchroVC animated:YES];
79 | } else {
80 | [self showAlertViewController:localize(@"TRTC-API-Example.ScreenEntrance.versionTips") message:nil handler:nil];
81 | }
82 | } else {
83 | ScreenAudienceViewController *audienceVC = [[ScreenAudienceViewController alloc] initWithNibName:@"ScreenAudienceViewController" bundle:nil];
84 | audienceVC.roomId = [_roomIdTextField.text intValue];
85 | audienceVC.userId = _userIdTextField.text;
86 | [self.navigationController pushViewController:audienceVC animated:YES];
87 | }
88 | }
89 |
90 | @end
91 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Basic/ScreenShare/TRTCBroadcastExtensionLauncher.h:
--------------------------------------------------------------------------------
1 | //
2 | // TRTCBroadcastExtensionLauncher.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by bluedang on 2021/4/15.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface TRTCBroadcastExtensionLauncher : NSObject
14 | + (instancetype) sharedInstance;
15 | + (void) launch;
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Basic/ScreenShare/TRTCBroadcastExtensionLauncher.m:
--------------------------------------------------------------------------------
1 | //
2 | // TRTCBroadcastExtensionLauncher.m
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by bluedang on 2021/4/15.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 | //
9 |
10 |
11 | #import
12 | #import
13 |
14 | #import "TRTCBroadcastExtensionLauncher.h"
15 |
16 | static TRTCBroadcastExtensionLauncher* launch;
17 |
18 | API_AVAILABLE(ios(12.0))
19 | @interface TRTCBroadcastExtensionLauncher()
20 | @property (strong, nonatomic) RPSystemBroadcastPickerView* systemBroacastExtensionPicker;
21 | @end
22 |
23 | @implementation TRTCBroadcastExtensionLauncher
24 |
25 | + (instancetype) sharedInstance {
26 | static dispatch_once_t onceToken;
27 | dispatch_once(&onceToken, ^{
28 | launch = [[self alloc] init];
29 | });
30 | return launch;
31 | }
32 |
33 | - (instancetype)init
34 | {
35 | self = [super init];
36 | if (self) {
37 | RPSystemBroadcastPickerView* picker =
38 | [[RPSystemBroadcastPickerView alloc] initWithFrame:CGRectMake(0, 0, 44, 44)];
39 | picker.showsMicrophoneButton = false;
40 | picker.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin;
41 | _systemBroacastExtensionPicker = picker;
42 |
43 | NSString *plugInPath = NSBundle.mainBundle.builtInPlugInsPath;
44 | if (!plugInPath) {
45 | return self;
46 | }
47 |
48 | NSArray* contents = [NSFileManager.defaultManager contentsOfDirectoryAtPath:plugInPath error:nil];
49 | for (NSString* content in contents) {
50 | NSURL* url = [NSURL fileURLWithPath:plugInPath];
51 | NSBundle* bundle = [NSBundle bundleWithPath:[url URLByAppendingPathComponent:content].path];
52 |
53 | NSDictionary* extension = [bundle.infoDictionary objectForKey:@"NSExtension"];
54 | if (extension == nil) { continue; }
55 | NSString* identifier = [extension objectForKey:@"NSExtensionPointIdentifier"];
56 | if ([identifier isEqualToString:@"com.apple.broadcast-services-upload"]) {
57 | picker.preferredExtension = bundle.bundleIdentifier;
58 | break;
59 | }
60 | }
61 | }
62 | return self;
63 | }
64 |
65 | + (void)launch {
66 | [[TRTCBroadcastExtensionLauncher sharedInstance] launch];
67 | }
68 |
69 | - (void)launch {
70 | for (UIView* view in _systemBroacastExtensionPicker.subviews) {
71 | UIButton* button = (UIButton*)view;
72 | [button sendActionsForControlEvents:UIControlEventAllTouchEvents];
73 | }
74 | }
75 |
76 | @end
77 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Basic/ScreenShare/TXReplayKit_Screen/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleDisplayName
8 | TRTC-API-Example
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleVersion
22 | 1
23 | NSExtension
24 |
25 | NSExtensionPointIdentifier
26 | com.apple.broadcast-services-upload
27 | NSExtensionPrincipalClass
28 | SampleHandler
29 | RPBroadcastProcessMode
30 | RPBroadcastProcessModeSampleBuffer
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Basic/ScreenShare/TXReplayKit_Screen/SampleHandler.h:
--------------------------------------------------------------------------------
1 | //
2 | // SampleHandler.h
3 | // TXReplayKit_Screen
4 | //
5 | // Created by dangjiahe on 2021/4/15.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface SampleHandler : RPBroadcastSampleHandler
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Basic/ScreenShare/TXReplayKit_Screen/SampleHandler.m:
--------------------------------------------------------------------------------
1 | //
2 | // SampleHandler.h
3 | // TXReplayKit_Screen
4 | //
5 | // Created by dangjiahe on 2021/4/15.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 | #import "SampleHandler.h"
9 | @import TXLiteAVSDK_ReplayKitExt;
10 |
11 | #define APPGROUP @"group.com.tencent.liteav.RPLiveStreamShare"
12 |
13 | @interface SampleHandler()
14 | @end
15 |
16 | @implementation SampleHandler
17 | - (void)broadcastStartedWithSetupInfo:(NSDictionary *)setupInfo {
18 | [[TXReplayKitExt sharedInstance] setupWithAppGroup:APPGROUP delegate:self];
19 | }
20 |
21 | - (void)broadcastPaused {
22 | // User has requested to pause the broadcast. Samples will stop being delivered.
23 | }
24 |
25 | - (void)broadcastResumed {
26 | // User has requested to resume the broadcast. Samples delivery will resume.
27 | }
28 |
29 | - (void)broadcastFinished {
30 | [[TXReplayKitExt sharedInstance] broadcastFinished];
31 | // User has requested to finish the broadcast.
32 | }
33 |
34 | #pragma mark - TXReplayKitExtDelegate
35 | - (void)broadcastFinished:(TXReplayKitExt *)broadcast reason:(TXReplayKitExtReason)reason
36 | {
37 | NSString *tip = @"";
38 | switch (reason) {
39 | case TXReplayKitExtReasonRequestedByMain:
40 | tip = NSLocalizedString(@"TRTC-API-Example.ScreenAnchor.liveStop", nil);
41 | break;
42 | case TXReplayKitExtReasonDisconnected:
43 | tip = NSLocalizedString(@"TRTC-API-Example.ScreenAnchor.appReset", nil);
44 | break;
45 | case TXReplayKitExtReasonVersionMismatch:
46 | tip = NSLocalizedString(@"TRTC-API-Example.ScreenAnchor.sdkError", nil);
47 | break;
48 | }
49 |
50 | NSError *error = [NSError errorWithDomain:NSStringFromClass(self.class)
51 | code:0
52 | userInfo:@{
53 | NSLocalizedFailureReasonErrorKey:tip
54 | }];
55 | [self finishBroadcastWithError:error];
56 | }
57 |
58 | - (void)processSampleBuffer:(CMSampleBufferRef)sampleBuffer withType:(RPSampleBufferType)sampleBufferType {
59 | [[TXReplayKitExt sharedInstance] sendSampleBuffer:sampleBuffer withType:sampleBufferType];
60 | }
61 | @end
62 |
63 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Basic/VideoCall/VideoCallingEnterViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // VideoCallingEnterViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by bluedang on 2021/4/12.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | //MARK: Video call example - room entry
14 | @interface VideoCallingEnterViewController : UIViewController
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Basic/VideoCall/VideoCallingEnterViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // VideoCallingEnterViewController.m
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by bluedang on 2021/4/12.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 | // TRTC video call entrance interface
9 | // Contains the following functions:
10 | // 1. Enter the room and generate the audio call interface
11 |
12 | #import "VideoCallingEnterViewController.h"
13 | #import "VideoCallingViewController.h"
14 |
15 | @interface VideoCallingEnterViewController ()
16 | @property (weak, nonatomic) IBOutlet UITextField *userIdTextField;
17 | @property (weak, nonatomic) IBOutlet UITextField *roomIdTextField;
18 | @property (weak, nonatomic) IBOutlet UILabel *inputRoomLabel;
19 | @property (weak, nonatomic) IBOutlet UILabel *inputUserLabel;
20 | @property (weak, nonatomic) IBOutlet UIButton *startButton;
21 | @end
22 |
23 | @implementation VideoCallingEnterViewController
24 |
25 | - (void)viewDidLoad {
26 | [super viewDidLoad];
27 |
28 | [self setupDefaultUIConfig];
29 | [self setupRandomId];
30 | }
31 |
32 | - (void)setupDefaultUIConfig {
33 | self.title = localize(@"TRTC-API-Example.VideoCallingEnter.Title");
34 | _inputRoomLabel.text = localize(@"TRTC-API-Example.VideoCallingEnter.EnterRoomNumber");
35 | _inputUserLabel.text = localize(@"TRTC-API-Example.VideoCallingEnter.EnterUserName");
36 | [_startButton setTitle:localize(@"TRTC-API-Example.VideoCallingEnter.EnterRoom") forState:UIControlStateNormal];
37 | }
38 |
39 | - (void)setupRandomId {
40 | _roomIdTextField.text = @"1356732";
41 | _userIdTextField.text = [NSString generateRandomUserId];
42 | }
43 |
44 | - (IBAction)onStartClick:(id)sender {
45 | VideoCallingViewController *videoCallingVC = [[VideoCallingViewController alloc]
46 | initWithRoomId:[_roomIdTextField.text intValue]
47 | userId:_userIdTextField.text];
48 | [self.navigationController pushViewController:videoCallingVC animated:YES];
49 | }
50 |
51 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
52 | [super touchesBegan:touches withEvent:event];
53 | [self.view endEditing:true];
54 | }
55 |
56 | @end
57 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Basic/VideoCall/VideoCallingViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // VideoCallingViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by bluedang on 2021/4/12.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | //MARK: Video call example - call interface
14 | @interface VideoCallingViewController : UIViewController
15 | - (instancetype)initWithRoomId:(UInt32)roomId userId:(NSString *)userId;
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Basic/VoiceChatRoom/VoiceChatRoomAnchorViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // VoiceChatRoomAnchorViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by adams on 2021/4/14.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface VoiceChatRoomAnchorViewController : UIViewController
14 |
15 | - (instancetype)initWithRoomId:(UInt32)roomId userId:(NSString *)userId;
16 |
17 | @end
18 |
19 | NS_ASSUME_NONNULL_END
20 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Basic/VoiceChatRoom/VoiceChatRoomAudienceViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // VoiceChatRoomAudienceViewController.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by adams on 2021/4/14.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface VoiceChatRoomAudienceViewController : UIViewController
14 |
15 | - (instancetype)initWithRoomId:(UInt32)roomId userId:(NSString *)userId;
16 |
17 | @end
18 |
19 | NS_ASSUME_NONNULL_END
20 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Basic/VoiceChatRoom/VoiceChatRoomEnterViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // VoiceChatRoomEnterViewController.h
3 | // TRTCSimpleDemo-OC
4 | //
5 | // Created by adams on 2021/4/14.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface VoiceChatRoomEnterViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Debug/GenerateTestUserSig.m:
--------------------------------------------------------------------------------
1 | //
2 | // SetBGMViewController.m
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by adams on 2021/4/20.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 | #import "GenerateTestUserSig.h"
9 | #import
10 | #import
11 |
12 | @implementation GenerateTestUserSig
13 |
14 | + (NSString *)genTestUserSig:(NSString *)identifier
15 | {
16 | CFTimeInterval current = CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970;
17 | long tlsTime = floor(current);
18 | NSMutableDictionary *obj = [@{@"TLS.ver": @"2.0",
19 | @"TLS.identifier": identifier,
20 | @"TLS.sdkappid": @(SDKAppID),
21 | @"TLS.expire": @(EXPIRETIME),
22 | @"TLS.time": @(tlsTime)} mutableCopy];
23 | NSMutableString *stringToSign = [[NSMutableString alloc] init];
24 | NSArray *keyOrder = @[@"TLS.identifier",
25 | @"TLS.sdkappid",
26 | @"TLS.time",
27 | @"TLS.expire"];
28 | for (NSString *key in keyOrder) {
29 | [stringToSign appendFormat:@"%@:%@\n", key, obj[key]];
30 | }
31 | NSLog(@"%@", stringToSign);
32 | //NSString *sig = [self sigString:stringToSign];
33 | NSString *sig = [self hmac:stringToSign];
34 |
35 | obj[@"TLS.sig"] = sig;
36 | NSLog(@"sig: %@", sig);
37 | NSError *error = nil;
38 | NSData *jsonToZipData = [NSJSONSerialization dataWithJSONObject:obj options:0 error:&error];
39 | if (error) {
40 | NSLog(@"[Error] json serialization failed: %@", error);
41 | return @"";
42 | }
43 |
44 | const Bytef* zipsrc = (const Bytef*)[jsonToZipData bytes];
45 | uLongf srcLen = jsonToZipData.length;
46 | uLong upperBound = compressBound(srcLen);
47 | Bytef *dest = (Bytef*)malloc(upperBound);
48 | uLongf destLen = upperBound;
49 | int ret = compress2(dest, &destLen, (const Bytef*)zipsrc, srcLen, Z_BEST_SPEED);
50 | if (ret != Z_OK) {
51 | NSLog(@"[Error] Compress Error %d, upper bound: %lu", ret, upperBound);
52 | free(dest);
53 | return @"";
54 | }
55 | NSString *result = [self base64URL: [NSData dataWithBytesNoCopy:dest length:destLen]];
56 | return result;
57 | }
58 |
59 | + (NSString *)hmac:(NSString *)plainText
60 | {
61 | const char *cKey = [SDKSECRETKEY cStringUsingEncoding:NSUTF8StringEncoding];
62 | const char *cData = [plainText cStringUsingEncoding:NSUTF8StringEncoding];
63 |
64 | unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
65 |
66 | CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
67 |
68 | NSData *hmacData = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
69 | return [hmacData base64EncodedStringWithOptions:0];
70 | }
71 |
72 | + (NSString *)base64URL:(NSData *)data
73 | {
74 | NSString *result = [data base64EncodedStringWithOptions:0];
75 | NSMutableString *final = [[NSMutableString alloc] init];
76 | const char *cString = [result cStringUsingEncoding:NSUTF8StringEncoding];
77 | for (int i = 0; i < result.length; ++ i) {
78 | char x = cString[i];
79 | switch(x){
80 | case '+':
81 | [final appendString:@"*"];
82 | break;
83 | case '/':
84 | [final appendString:@"-"];
85 | break;
86 | case '=':
87 | [final appendString:@"_"];
88 | break;
89 | default:
90 | [final appendFormat:@"%c", x];
91 | break;
92 | }
93 | }
94 | return final;
95 | }
96 |
97 | @end
98 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Debug/UIViewController+KeyBoard.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIViewController+KeyBoard.h
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by janejntang on 2022/7/28.
6 | // Copyright © 2022 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface UIViewController (KeyBoard)
14 | - (void)addKeyboardObserver;
15 | - (void)removeKeyboardObserver;
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Debug/UIViewController+KeyBoard.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIViewController+KeyBoard.m
3 | // TRTC-API-Example-OC
4 | //
5 | // Created by janejntang on 2022/7/28.
6 | // Copyright © 2022 Tencent. All rights reserved.
7 | //
8 |
9 | #import "UIViewController+KeyBoard.h"
10 |
11 | @implementation UIViewController (KeyBoard)
12 |
13 | - (void)addKeyboardObserver {
14 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
15 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
16 | }
17 |
18 | - (void)removeKeyboardObserver {
19 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
20 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
21 | }
22 |
23 | - (BOOL)keyboardWillShow:(NSNotification *)noti {
24 | CGFloat animationDuration = [[[noti userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
25 | CGRect keyboardBounds = [[[noti userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
26 | CGAffineTransform transform = CGAffineTransformIdentity;
27 | [UIView animateWithDuration:animationDuration animations:^{
28 | self.view.transform = CGAffineTransformTranslate(transform, 0, keyboardBounds.origin.y - self.view.frame.size.height);
29 | }];
30 | return YES;
31 | }
32 |
33 | - (BOOL)keyboardWillHide:(NSNotification *)noti {
34 | CGFloat animationDuration = [[[noti userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
35 | [UIView animateWithDuration:animationDuration animations:^{
36 | self.view.transform = CGAffineTransformIdentity;
37 | }];
38 | return YES;
39 | }
40 | @end
41 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment the next line to define a global platform for your project
2 | platform :ios, '11.0'
3 |
4 | target 'TRTC-API-Example-OC' do
5 | # Comment the next line if you don't want to use dynamic frameworks
6 | use_frameworks!
7 |
8 | # Pods for TRTC-API-Example-OC
9 | pod 'TXLiteAVSDK_TRTC'
10 | end
11 |
12 | target 'TXReplayKit_Screen' do
13 | # Comment the next line if you don't want to use dynamic frameworks
14 | use_frameworks!
15 |
16 | # Pods for TXReplayKit_Screen
17 | pod 'TXLiteAVSDK_TRTC/ReplayKitExt'
18 | end
19 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - TXLiteAVSDK_TRTC (11.1.14143):
3 | - TXLiteAVSDK_TRTC/TRTC (= 11.1.14143)
4 | - TXLiteAVSDK_TRTC/ReplayKitExt (11.1.14143)
5 | - TXLiteAVSDK_TRTC/TRTC (11.1.14143)
6 |
7 | DEPENDENCIES:
8 | - TXLiteAVSDK_TRTC
9 | - TXLiteAVSDK_TRTC/ReplayKitExt
10 |
11 | SPEC REPOS:
12 | trunk:
13 | - TXLiteAVSDK_TRTC
14 |
15 | SPEC CHECKSUMS:
16 | TXLiteAVSDK_TRTC: 15b46120bfb5227c4f07a03d7b73b2530a4034bf
17 |
18 | PODFILE CHECKSUM: d119721017e2234ff86499d221e4187688f6dd77
19 |
20 | COCOAPODS: 1.12.1
21 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/README-zh_CN.md:
--------------------------------------------------------------------------------
1 | # TRTC API-Example
2 | _中文 | [English](README.md)_
3 |
4 | ## 前言
5 | 这个开源示例Demo主要演示了 [TRTC 实时音视频 SDK](https://cloud.tencent.com/document/product/647/32689) 部分API的使用示例,帮助开发者可以更好的理解 TRTC 实时音视频 SDK 的API,从而快速实现一些音视频场景的基本功能。
6 |
7 | ## 结构说明
8 | 在这个示例项目中包含了以下场景:(带上对应的跳转目录,方便用户快速浏览感兴趣的功能)
9 |
10 | - 基础功能
11 | - [语音通话](./Basic/AudioCall)
12 | - [视频通话](./Basic/VideoCall)
13 | - [视频互动直播](./Basic/Live)
14 | - [语音互动直播](./Basic/VoiceChatRoom)
15 | - [录屏直播](./Basic/ScreenShare)
16 | - 进阶功能
17 | - [字符串房间号](./Advanced/StringRoomId)
18 | - [画质设定](./Advanced/SetVideoQuality)
19 | - [音质设定](./Advanced/SetAudioQuality)
20 | - [渲染控制](./Advanced/SetRenderParams)
21 | - [网络测速](./Advanced/SpeedTest)
22 | - [CDN发布](./Advanced/PushCDN)
23 | - [自定义视频采集&渲染](./Advanced/CustomCamera)
24 | - [设置音效](./Advanced/SetAudioEffect)
25 | - [设置背景音乐](./Advanced/SetBackgroundMusic)
26 | - [本地视频文件分享](./Advanced/LocalVideoShare)
27 | - [本地视频录制](./Advanced/LocalRecord)
28 | - [加入多个房间](./Advanced/JoinMultipleRoom)
29 | - [收发SEI消息](./Advanced/SEIMessage)
30 | - [快速切换房间](./Advanced/SwitchRoom)
31 | - [跨房PK](./Advanced/RoomPk)
32 | - [第三方美颜](./Advanced/ThirdBeauty)
33 | - [画中画功能](./Advanced/PictureInPicture)
34 |
35 |
36 | ## 环境准备
37 | - Xcode 11.0及以上版本
38 | - 请确保您的项目已设置有效的开发者签名
39 |
40 |
41 | ## 运行示例
42 |
43 | ### 前提条件
44 | 您已 [注册腾讯云](https://cloud.tencent.com/document/product/378/17985) 账号,并完成 [实名认证](https://cloud.tencent.com/document/product/378/3629)。
45 |
46 |
47 | ### 申请 SDKAPPID 和 SDKSECRETKEY
48 | 1. 登录实时音视频控制台,选择【开发辅助】>【[快速跑通Demo](https://console.cloud.tencent.com/trtc/quickstart)】。
49 | 2. 单击【立即开始】,输入您的应用名称,例如`TestTRTC`,单击【创建应用】。
50 |
51 | 
52 | 3. 创建应用完成后,单击【我已下载,下一步】,可以查看 SDKAppID 和密钥信息。
53 |
54 |
55 | ### 配置 Demo 工程文件
56 | 1. 打开 Debug 目录下的 [GenerateTestUserSig.h](debug/GenerateTestUserSig.h) 文件。
57 | 2. 配置`GenerateTestUserSig.h`文件中的两个参数:
58 | - SDKAPPID:替换该变量值为上一步骤中在页面上看到的 SDKAppID。
59 | - SDKSECRETKEY:替换该变量值为上一步骤中在页面上看到的密钥。
60 | 
61 |
62 | 4. 返回实时音视频控制台,单击【粘贴完成,下一步】。
63 | 5. 单击【关闭指引,进入控制台管理应用】。
64 |
65 | >!本文提到的生成 UserSig 的方案是在客户端代码中配置 SDKSECRETKEY,该方法中 SDKSECRETKEY 很容易被反编译逆向破解,一旦您的密钥泄露,攻击者就可以盗用您的腾讯云流量,因此**该方法仅适合本地跑通 Demo 和功能调试**。
66 | >正确的 UserSig 签发方式是将 UserSig 的计算代码集成到您的服务端,并提供面向 App 的接口,在需要 UserSig 时由您的 App 向业务服务器发起请求获取动态 UserSig。更多详情请参见 [服务端生成 UserSig](https://cloud.tencent.com/document/product/647/17275#Server)。
67 |
68 | ### 配置CDN 相关(可选)
69 | 如果您需要使用CDN相关业务,比如主播使用TRTC SDK互动连麦,观众端播放CDN流这样的方式,您还需要配置如下三个**直播**相关参数:
70 | - `BIZID`;
71 | - `APPID`;
72 | - `CDN_DOMAIN_NAME`;
73 |
74 | 
75 |
76 | 详细操作可以参考 [实现 CDN 直播观看](https://cloud.tencent.com/document/product/647/16826#.E9.80.82.E7.94.A8.E5.9C.BA.E6.99.AF)
77 |
78 | >注意:
79 | >本文提到的生成 UserSig 的方案是在客户端代码中配置 SDKSECRETKEY,该方法中 SDKSECRETKEY 很容易被反编译逆向破解,一旦您的密钥泄露,攻击者就可以盗用您的腾讯云流量,因此**该方法仅适合本地跑通 Demo 和功能调试**。
80 | >正确的 UserSig 签发方式请参见 [服务端生成 UserSig](https://cloud.tencent.com/document/product/647/17275#Server)。
81 |
82 | ### 编译运行
83 | 使用 XCode(11.0及以上的版本)打开源码目录下的 TRTC-API-Example-OC.xcodeproj
84 | > 上述流程并没有解答您的疑问,你可以[点击此处](https://wj.qq.com/s2/8393513/f442/)反馈,我们的**工程师妹子**会尽快处理!
85 |
86 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/README.md:
--------------------------------------------------------------------------------
1 | # TRTC API-Example
2 | [中文](README-zh_CN.md) | English
3 |
4 | ## Background
5 | This open-source demo shows how to use some APIs of the [TRTC SDK](https://www.tencentcloud.com/document/product/647/34615) to help you better understand the APIs and use them to implement some basic TRTC features.
6 |
7 | ## Contents
8 | This demo covers the following features (click to view the details of a feature):
9 |
10 | - Basic Features
11 | - [Audio Call](./Basic/AudioCall)
12 | - [Video Call](./Basic/VideoCall)
13 | - [Interactive Live Video Streaming](./Basic/Live)
14 | - [Interactive Live Audio Streaming](./Basic/VoiceChatRoom)
15 | - [Screen Sharing Live Streaming](./Basic/ScreenShare)
16 | - Advanced Features
17 | - [String-type Room IDs](./Advanced/StringRoomId)
18 | - [Video Quality Setting](./Advanced/SetVideoQuality)
19 | - [Audio Quality Setting](./Advanced/SetAudioQuality)
20 | - [Rendering Control](./Advanced/SetRenderParams)
21 | - [Network Speed Testing](./Advanced/SpeedTest)
22 | - [CDN Publishing](./Advanced/PushCDN)
23 | - [Custom Video Capturing & Rendering](./Advanced/CustomCamera)
24 | - [Audio Effect Setting](./Advanced/SetAudioEffect)
25 | - [Background Music Setting](./Advanced/SetBackgroundMusic)
26 | - [Local Video Sharing](./Advanced/LocalVideoShare)
27 | - [Local Video Recording](./Advanced/LocalRecord)
28 | - [Multiple Room Entry](./Advanced/JoinMultipleRoom)
29 | - [SEI Message Receiving/Sending](./Advanced/SEIMessage)
30 | - [Room Switching](./Advanced/SwitchRoom)
31 | - [Cross-Room Competition](./Advanced/RoomPk)
32 | - [Third-Party Beauty Filters](./Advanced/ThirdBeauty)
33 |
34 | ## Environment Requirements
35 | - Xcode 11.0 and above
36 | - Please make sure that your project has set a valid developer signature
37 |
38 |
39 | ## Demo Run Example
40 |
41 | #### Prerequisites
42 | You have [signed up for a Tencent Cloud account](https://intl.cloud.tencent.com/document/product/378/17985) and completed [identity verification](https://intl.cloud.tencent.com/document/product/378/3629).
43 |
44 |
45 | ### Obtaining `SDKAPPID` and `SDKSECRETKEY`
46 | 1. Log in to the TRTC console and select **Application Management** > **[Create application](https://console.tencentcloud.com/trtc/app/create)**.
47 | 2. Enter an application name such as `TestTRTC`, and click **Next**.
48 |
49 | 
50 | 3. Click **Next** to view your `SDKAppID` and key.
51 |
52 |
53 | ### Configuring demo project files
54 | 1. Open the [GenerateTestUserSig.h](debug/GenerateTestUserSig.h) file in the Debug directory.
55 | 2. Configure two parameters in the `GenerateTestUserSig.h` file:
56 | - `SDKAPPID`: `PLACEHOLDER` by default. Set it to the actual `SDKAppID`.
57 | - `SDKSECRETKEY`: left empty by default. Set it to the actual key.
58 | 
59 |
60 | 3. Return to the TRTC console and click **Next**.
61 | 4. Click **Return to Overview Page**.
62 |
63 | >!The method for generating `UserSig` described in this document involves configuring `SDKSECRETKEY` in client code. In this method, `SDKSECRETKEY` may be easily decompiled and reversed, and if your key is disclosed, attackers can steal your Tencent Cloud traffic. Therefore, **this method is suitable only for the local execution and debugging of the demo**.
64 | >The correct `UserSig` distribution method is to integrate the calculation code of `UserSig` into your server and provide an application-oriented API. When `UserSig` is needed, your application can make a request to the business server for dynamic `UserSig`. For more information, please see [How to Calculate UserSig](https://www.tencentcloud.com/document/product/647/35166).
65 |
66 | ## Configuring CDN parameters (optional)
67 | To use CDN services, which are needed for co-anchoring, CDN playback, etc., you need to configure three **live streaming** parameters.
68 |
69 | For detailed instructions, see [CDN Relayed Live Streaming](https://www.tencentcloud.com/document/product/647/47858).
70 |
71 |
72 | ### Compiling and running the project
73 | Use XCode (11.0 and above) to open TRTC-API-Example-OC.xcodeproj in the source directory
74 |
75 |
76 | ## Contact Us
77 | - If you have questions, see [FAQs](https://www.tencentcloud.com/document/product/647/36057).
78 |
79 | - To learn about how the TRTC SDK can be used in different scenarios, see [Sample Code](https://www.tencentcloud.com/document/product/647/42963).
80 |
81 | - For complete API documentation, see [SDK API Documentation](https://www.tencentcloud.com/document/product/647/35119).
82 |
83 | - Communication & Feedback
84 | Welcome to join our Telegram Group to communicate with our professional engineers! We are more than happy to hear from you~
85 | Click to join: [https://t.me/+EPk6TMZEZMM5OGY1](https://t.me/+EPk6TMZEZMM5OGY1)
86 | Or scan the QR code
87 |
88 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Resource/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Resource/Assets.xcassets/AppIcon.appiconset/AppIcon1024x1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tencent-RTC/TRTC_iOS/ff2c8291d9f408269d19e5b30f7e4c56463210ea/TRTC-API-Example-OC/Resource/Assets.xcassets/AppIcon.appiconset/AppIcon1024x1024.png
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Resource/Assets.xcassets/AppIcon.appiconset/AppIcon120x120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tencent-RTC/TRTC_iOS/ff2c8291d9f408269d19e5b30f7e4c56463210ea/TRTC-API-Example-OC/Resource/Assets.xcassets/AppIcon.appiconset/AppIcon120x120.png
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Resource/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "2x",
6 | "size" : "20x20"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "3x",
11 | "size" : "20x20"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "29x29"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "3x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "40x40"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "40x40"
32 | },
33 | {
34 | "filename" : "AppIcon120x120.png",
35 | "idiom" : "iphone",
36 | "scale" : "2x",
37 | "size" : "60x60"
38 | },
39 | {
40 | "idiom" : "iphone",
41 | "scale" : "3x",
42 | "size" : "60x60"
43 | },
44 | {
45 | "idiom" : "ipad",
46 | "scale" : "1x",
47 | "size" : "20x20"
48 | },
49 | {
50 | "idiom" : "ipad",
51 | "scale" : "2x",
52 | "size" : "20x20"
53 | },
54 | {
55 | "idiom" : "ipad",
56 | "scale" : "1x",
57 | "size" : "29x29"
58 | },
59 | {
60 | "idiom" : "ipad",
61 | "scale" : "2x",
62 | "size" : "29x29"
63 | },
64 | {
65 | "idiom" : "ipad",
66 | "scale" : "1x",
67 | "size" : "40x40"
68 | },
69 | {
70 | "idiom" : "ipad",
71 | "scale" : "2x",
72 | "size" : "40x40"
73 | },
74 | {
75 | "idiom" : "ipad",
76 | "scale" : "1x",
77 | "size" : "76x76"
78 | },
79 | {
80 | "idiom" : "ipad",
81 | "scale" : "2x",
82 | "size" : "76x76"
83 | },
84 | {
85 | "idiom" : "ipad",
86 | "scale" : "2x",
87 | "size" : "83.5x83.5"
88 | },
89 | {
90 | "filename" : "AppIcon1024x1024.png",
91 | "idiom" : "ios-marketing",
92 | "scale" : "1x",
93 | "size" : "1024x1024"
94 | }
95 | ],
96 | "info" : {
97 | "author" : "xcode",
98 | "version" : 1
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Resource/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Resource/Assets.xcassets/audiocall_user_portrait.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "audiocall_user_portrait.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "audiocall_user_portrait-1.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Resource/Assets.xcassets/audiocall_user_portrait.imageset/audiocall_user_portrait-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tencent-RTC/TRTC_iOS/ff2c8291d9f408269d19e5b30f7e4c56463210ea/TRTC-API-Example-OC/Resource/Assets.xcassets/audiocall_user_portrait.imageset/audiocall_user_portrait-1.png
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Resource/Assets.xcassets/audiocall_user_portrait.imageset/audiocall_user_portrait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tencent-RTC/TRTC_iOS/ff2c8291d9f408269d19e5b30f7e4c56463210ea/TRTC-API-Example-OC/Resource/Assets.xcassets/audiocall_user_portrait.imageset/audiocall_user_portrait.png
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Resource/Assets.xcassets/launchimage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "launchimage@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "launchimage@3x.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Resource/Assets.xcassets/launchimage.imageset/launchimage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tencent-RTC/TRTC_iOS/ff2c8291d9f408269d19e5b30f7e4c56463210ea/TRTC-API-Example-OC/Resource/Assets.xcassets/launchimage.imageset/launchimage@2x.png
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Resource/Assets.xcassets/launchimage.imageset/launchimage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tencent-RTC/TRTC_iOS/ff2c8291d9f408269d19e5b30f7e4c56463210ea/TRTC-API-Example-OC/Resource/Assets.xcassets/launchimage.imageset/launchimage@3x.png
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Resource/Localized/AppLocalized.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppLocalized.h
3 | // TXLiteAVDemo
4 | //
5 | // Created by gg on 2021/3/17.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | //MARK: Base
14 | extern NSString *localizeFromTable(NSString *key, NSString *table);
15 |
16 | //MARK: Replace String
17 | extern NSString *localizeReplace(NSString *origin, NSString *xxx_replace);
18 | extern NSString *localizeReplaceTwoCharacter(NSString *origin, NSString *xxx_replace, NSString *yyy_replace);
19 |
20 | extern NSString *const localize_TableName;
21 | extern NSString *localize(NSString *key);
22 |
23 | NS_ASSUME_NONNULL_END
24 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Resource/Localized/AppLocalized.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppLocalized.m
3 | // TXLiteAVDemo
4 | //
5 | // Created by gg on 2021/3/17.
6 | // Copyright © 2021 Tencent. All rights reserved.
7 | //
8 |
9 | #import "AppLocalized.h"
10 |
11 | //MARK: Base
12 | NSString *localizeFromTable(NSString *key, NSString *table) {
13 | return [NSBundle.mainBundle localizedStringForKey:key value:@"" table:table];
14 | }
15 |
16 | //MARK: Replace String
17 | NSString *localizeReplace(NSString *origin, NSString *xxx_replace) {
18 | if (xxx_replace == nil) { xxx_replace = @"";}
19 | return [origin stringByReplacingOccurrencesOfString:@"xxx" withString:xxx_replace];
20 | }
21 |
22 | NSString *localizeReplaceTwoCharacter(NSString *origin, NSString *xxx_replace, NSString *yyy_replace) {
23 | if (yyy_replace == nil) { yyy_replace = @"";}
24 | return [localizeReplace(localize(origin), xxx_replace) stringByReplacingOccurrencesOfString:@"yyy" withString:yyy_replace];
25 | }
26 |
27 | NSString *const localize_TableName = @"Localized";
28 | NSString *localize(NSString *key) {
29 | return localizeFromTable(key, localize_TableName);
30 | }
31 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Resource/Localized/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /*
2 | InfoPlist.strings
3 | TRTC-API-Example-OC
4 |
5 | Created by adams on 2021/4/26.
6 |
7 | */
8 |
9 | "CFBundleDisplayName" = "TRTC-API-Example";
10 | "NSCameraUsageDescription" = "TRTC-API-Example 需要访问你的相机权限,开启后录制的视频才会有画面";
11 | "NSMicrophoneUsageDescription" = "TRTC-API-Example 需要访问你的麦克风权限,开启后录制的视频才会有声音";
12 | "NSPhotoLibraryAddUsageDescription" = "TRTC-API-Example 需要访问你的相册权限,开启后才能保存编辑的文件";
13 | "NSPhotoLibraryUsageDescription" = "TRTC-API-Example 需要访问你的相册权限,开启后才能编辑视频文件";
14 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/Resource/Localized/zh-Hans.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /*
2 | InfoPlist.strings
3 | TRTC-API-Example-OC
4 |
5 | Created by adams on 2021/4/26.
6 |
7 | */
8 |
9 | "CFBundleDisplayName" = "TRTC-API-Example";
10 | "NSCameraUsageDescription" = "TRTC-API-Example 需要访问你的相机权限,开启后录制的视频才会有画面";
11 | "NSMicrophoneUsageDescription" = "TRTC-API-Example 需要访问你的麦克风权限,开启后录制的视频才会有声音";
12 | "NSPhotoLibraryAddUsageDescription" = "TRTC-API-Example 需要访问你的相册权限,开启后才能保存编辑的文件";
13 | "NSPhotoLibraryUsageDescription" = "TRTC-API-Example 需要访问你的相册权限,开启后才能编辑视频文件";
14 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/TRTC-API-Example-OC.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/TRTC-API-Example-OC.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/TRTC-API-Example-OC.xcodeproj/project.xcworkspace/xcuserdata/tangjianing.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tencent-RTC/TRTC_iOS/ff2c8291d9f408269d19e5b30f7e4c56463210ea/TRTC-API-Example-OC/TRTC-API-Example-OC.xcodeproj/project.xcworkspace/xcuserdata/tangjianing.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/TRTC-API-Example-OC.xcodeproj/xcshareddata/xcschemes/TRTC-API-Example-OC.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
45 |
51 |
52 |
53 |
54 |
60 |
62 |
68 |
69 |
70 |
71 |
73 |
74 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/TRTC-API-Example-OC.xcodeproj/xcshareddata/xcschemes/TXReplayKit_Screen.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
6 |
9 |
10 |
16 |
22 |
23 |
24 |
30 |
36 |
37 |
38 |
39 |
40 |
45 |
46 |
47 |
48 |
60 |
62 |
68 |
69 |
70 |
71 |
78 |
80 |
86 |
87 |
88 |
89 |
91 |
92 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/TRTC-API-Example-OC.xcodeproj/xcuserdata/tangjianing.xcuserdatad/xcschemes/Copy of Copy of TRTC-API-Example-OC.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
45 |
51 |
52 |
53 |
54 |
60 |
62 |
68 |
69 |
70 |
71 |
73 |
74 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/TRTC-API-Example-OC.xcodeproj/xcuserdata/tangjianing.xcuserdatad/xcschemes/Copy of TRTC-API-Example-OC.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
45 |
51 |
52 |
53 |
54 |
60 |
62 |
68 |
69 |
70 |
71 |
73 |
74 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/TRTC-API-Example-OC.xcodeproj/xcuserdata/tangjianing.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | Copy of Copy of TRTC-API-Example-OC.xcscheme
8 |
9 | orderHint
10 | 1
11 |
12 | Copy of TRTC-API-Example-OC.xcscheme
13 |
14 | orderHint
15 | 0
16 |
17 | TRTC-API-Example-OC.xcscheme_^#shared#^_
18 |
19 | orderHint
20 | 2
21 |
22 | TXReplayKit_Screen.xcscheme_^#shared#^_
23 |
24 | orderHint
25 | 3
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/TRTC-API-Example-OC.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/TRTC-API-Example-OC.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/TRTC-API-Example-OC/TRTC-API-Example-OC.xcworkspace/xcuserdata/wangyan.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tencent-RTC/TRTC_iOS/ff2c8291d9f408269d19e5b30f7e4c56463210ea/TRTC-API-Example-OC/TRTC-API-Example-OC.xcworkspace/xcuserdata/wangyan.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tencent-RTC/TRTC_iOS/ff2c8291d9f408269d19e5b30f7e4c56463210ea/TRTC-API-Example-Swift/.DS_Store
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## User settings
6 | xcuserdata/
7 |
8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
9 | *.xcscmblueprint
10 | *.xccheckout
11 |
12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
13 | build/
14 | DerivedData/
15 | *.moved-aside
16 | *.pbxuser
17 | !default.pbxuser
18 | *.mode1v3
19 | !default.mode1v3
20 | *.mode2v3
21 | !default.mode2v3
22 | *.perspectivev3
23 | !default.perspectivev3
24 |
25 | ## Obj-C/Swift specific
26 | *.hmap
27 |
28 | ## App packaging
29 | *.ipa
30 | *.dSYM.zip
31 | *.dSYM
32 |
33 | ## Playgrounds
34 | timeline.xctimeline
35 | playground.xcworkspace
36 |
37 | # Swift Package Manager
38 | #
39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
40 | # Packages/
41 | # Package.pins
42 | # Package.resolved
43 | # *.xcodeproj
44 | #
45 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
46 | # hence it is not needed unless you have added a package configuration file to your project
47 | # .swiftpm
48 |
49 | .build/
50 |
51 | # CocoaPods
52 | #
53 | # We recommend against adding the Pods directory to your .gitignore. However
54 | # you should judge for yourself, the pros and cons are mentioned at:
55 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
56 | #
57 | Pods/
58 | #
59 | # Add this line if you want to avoid checking in source code from the Xcode workspace
60 | # *.xcworkspace
61 |
62 | # Carthage
63 | #
64 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
65 | # Carthage/Checkouts
66 |
67 | Carthage/Build/
68 |
69 | # Accio dependency management
70 | Dependencies/
71 | .accio/
72 |
73 | # fastlane
74 | #
75 | # It is recommended to not store the screenshots in the git repo.
76 | # Instead, use fastlane to re-generate the screenshots whenever they are needed.
77 | # For more information about the recommended setup visit:
78 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
79 |
80 | fastlane/report.xml
81 | fastlane/Preview.html
82 | fastlane/screenshots/**/*.png
83 | fastlane/test_output
84 |
85 | # Code Injection
86 | #
87 | # After new code Injection tools there's a generated folder /iOSInjectionProject
88 | # https://github.com/johnno1962/injectionforxcode
89 |
90 | iOSInjectionProject/
91 |
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tencent-RTC/TRTC_iOS/ff2c8291d9f408269d19e5b30f7e4c56463210ea/TRTC-API-Example-Swift/.gitkeep
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/Advanced/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tencent-RTC/TRTC_iOS/ff2c8291d9f408269d19e5b30f7e4c56463210ea/TRTC-API-Example-Swift/Advanced/.gitkeep
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/Advanced/CustomCamera/Render/CustomCameraFrameRender.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CustomCameraFrameRender.swift
3 | // TRTC-API-Example-Swift
4 | //
5 | // Created by janejntang on 2022/7/4.
6 | // Copyright © 2022 Tencent. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 | import TXLiteAVSDK_TRTC
12 | import CoreFoundation
13 | /*
14 | Custom Video Capturing and Rendering
15 | TRTC APP supports custom video data collection. This document shows how to customize the data collected by rendering.
16 | 1. Customized rendering of collected data : onRenderVideoFrame()
17 | For more information, please see https://cloud.tencent.com/document/product/647/34066
18 | */
19 | class CustomCameraFrameRender:NSObject {
20 |
21 | var localVideoView: UIImageView
22 | let userVideoViews : NSMutableDictionary
23 | let queue : DispatchQueue
24 |
25 | override init() {
26 | userVideoViews = NSMutableDictionary()
27 | queue = DispatchQueue(label: "")
28 | localVideoView = UIImageView()
29 | }
30 |
31 | func start(userId : String?, videoView: UIImageView) {
32 | if let userID = userId{
33 | userVideoViews.setObject(videoView, forKey: userID as NSCopying)
34 | }else{
35 | localVideoView = videoView
36 | }
37 | }
38 |
39 | func onRenderVideoFrame(frame: TRTCVideoFrame , userId: String? ,streamType: TRTCVideoStreamType) {
40 | let pixelBuffer = frame.pixelBuffer
41 | DispatchQueue.main.async {
42 | var videoView = UIImageView()
43 | if let userID = userId{
44 | guard let videoImageView = self.userVideoViews.object(forKey: userID) as? UIImageView else { return }
45 | videoView = videoImageView
46 | }else{
47 | videoView = self.localVideoView
48 | }
49 | if let pixelBuffer = pixelBuffer {
50 | videoView.image = UIImage.init(ciImage: CIImage.init(cvImageBuffer: pixelBuffer))
51 | videoView.contentMode = .scaleAspectFit
52 | }
53 | }
54 | }
55 |
56 | func stop() {
57 | UIGraphicsBeginImageContext(localVideoView.bounds.size)
58 | let color = UIColor()
59 | let image = UIGraphicsGetImageFromCurrentImageContext()
60 | UIGraphicsEndImageContext()
61 | localVideoView.image = image
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/Advanced/JoinMultipleRoom/SubCloudHelper.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SubCloudHelper.swift
3 | // TRTC-API-Example-Swift
4 | //
5 | // Created by janejntang on 2022/7/5.
6 | // Copyright © 2022 Tencent. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import ObjectiveC
11 | import TXLiteAVSDK_TRTC
12 |
13 | @objc protocol SubCloudHelperDelegate : NSObjectProtocol {
14 | @objc optional func onUserVideoAvailableWithSubId(subId: UInt32, userId: String, available: Bool)
15 | }
16 |
17 | class SubCloudHelper:NSObject,TRTCCloudDelegate {
18 |
19 | var trtcCloud = TRTCCloud()
20 | var subId : UInt32 = 0
21 | weak var delegate : SubCloudHelperDelegate? = nil
22 |
23 | override init() {
24 | super.init()
25 | trtcCloud.delegate = self
26 | }
27 |
28 | func getCloud()->TRTCCloud {
29 | return trtcCloud
30 | }
31 |
32 | func onUserVideoAvailable(_ userId: String, available: Bool) {
33 | if self.delegate?.onUserVideoAvailableWithSubId?(subId: subId, userId: userId, available: available) == nil {
34 | return
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/App/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // TRTC-API-Example-Swift
4 | //
5 | // Created by peteryhchen on 2022/6/17.
6 | //
7 |
8 | import UIKit
9 |
10 | @main
11 | class AppDelegate: UIResponder, UIApplicationDelegate {
12 |
13 |
14 |
15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
16 | // Override point for customization after application launch.
17 | return true
18 | }
19 |
20 | // MARK: UISceneSession Lifecycle
21 |
22 | func application(_ application: UIApplication,
23 | configurationForConnecting connectingSceneSession: UISceneSession,
24 | options: UIScene.ConnectionOptions) -> UISceneConfiguration {
25 | // Called when a new scene session is being created.
26 | // Use this method to select a configuration to create the new scene with.
27 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
28 | }
29 |
30 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
31 | // Called when the user discards a scene session.
32 | // If any sessions were discarded while the application was not running,
33 | // this will be called shortly after application:didFinishLaunchingWithOptions.
34 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
35 | }
36 |
37 |
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/App/Extension/UIColor+hex.swift:
--------------------------------------------------------------------------------
1 |
2 | //
3 | // UIColor+hex.swift
4 | // TRTCVoiceRoomDemo
5 | //
6 | // Created by abyyxwang on 2020/6/4.
7 | // Copyright © 2020 tencent. All rights reserved.
8 | //
9 |
10 |
11 | //
12 | // GenerateTestUserSig.swift
13 | // TRTC-API-Example-Swift
14 | //
15 | // Created by janejntang on 2022/6/24.
16 | // Copyright © 2022 Tencent. All rights reserved.
17 | //
18 |
19 | import UIKit
20 |
21 |
22 | extension UIColor {
23 | public convenience init(red: Int, green: Int, blue: Int, alpha: CGFloat = 1.0) {
24 | self.init(
25 | red: CGFloat(red) / 255.0,
26 | green: CGFloat(green) / 255.0,
27 | blue: CGFloat(blue) / 255.0,
28 | alpha: alpha
29 | )
30 | }
31 |
32 | // Set color value
33 | // Set color value via hexadecimal and alpha (style: 0xff00ff)
34 | public convenience init(_ hex: Int, alpha: CGFloat = 1.0) {
35 | assert(0...0xFFFFFF ~= hex, "The color hex value must between 0 to 0XFFFFFF")
36 | let red = (hex & 0xFF0000) >> 16
37 | let green = (hex & 0x00FF00) >> 8
38 | let blue = (hex & 0x0000FF)
39 | self.init(red: red, green: green, blue: blue, alpha: alpha)
40 | }
41 |
42 | public convenience init(_ hex: String) {
43 | var red: CGFloat = 0.0
44 | var green: CGFloat = 0.0
45 | var blue: CGFloat = 0.0
46 | var alpha: CGFloat = 1.0
47 | let scanner = Scanner.init(string: hex)
48 | var hexValue: CUnsignedLongLong = 0
49 | if scanner.scanHexInt64(&hexValue) {
50 | switch (hex.count) {
51 | case 3:
52 | red = CGFloat((hexValue & 0xF00) >> 8) / 15.0
53 | green = CGFloat((hexValue & 0x0F0) >> 4) / 15.0
54 | blue = CGFloat(hexValue & 0x00F) / 15.0
55 | case 4:
56 | red = CGFloat((hexValue & 0xF000) >> 12) / 15.0
57 | green = CGFloat((hexValue & 0x0F00) >> 8) / 15.0
58 | blue = CGFloat((hexValue & 0x00F0) >> 4) / 15.0
59 | alpha = CGFloat(hexValue & 0x000F) / 15.0
60 | case 6:
61 | red = CGFloat((hexValue & 0xFF0000) >> 16) / 255.0
62 | green = CGFloat((hexValue & 0x00FF00) >> 8) / 255.0
63 | blue = CGFloat(hexValue & 0x0000FF) / 255.0
64 | case 8:
65 | red = CGFloat((hexValue & 0xFF000000) >> 24) / 255.0
66 | green = CGFloat((hexValue & 0x00FF0000) >> 16) / 255.0
67 | blue = CGFloat((hexValue & 0x0000FF00) >> 8) / 255.0
68 | alpha = CGFloat(hexValue & 0x000000FF) / 255.0
69 | default:
70 | break
71 | }
72 | }
73 | self.init(red: red, green: green, blue: blue, alpha: alpha)
74 | }
75 |
76 | // Convert colors to pictures
77 | public func trans2Image(imageSize : CGSize) -> UIImage {
78 | let rect = CGRect(x: 0, y: 0, width: imageSize.width, height: imageSize.height)
79 | UIGraphicsBeginImageContext(rect.size)
80 | let context = UIGraphicsGetCurrentContext()
81 | context?.setFillColor(self.cgColor)
82 | context?.fill(rect)
83 | let theImage = UIGraphicsGetImageFromCurrentImageContext()
84 | UIGraphicsEndImageContext()
85 | return theImage ?? UIImage()
86 | }
87 | }
88 |
89 | public extension UIColor {
90 | public static let themeTintColor = UIColor.init(0x5E6FA3)
91 | }
92 |
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/App/Home/SubViews/HomeTableSectionHeaderView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HomeTableSectionHeaderView.swift
3 | // TRTC-API-Example-Swift
4 | //
5 | // Created by peteryhchen on 2022/6/22.
6 | // Copyright © 2022 Tencent. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class HomeTableSectionHeaderView : UITableViewHeaderFooterView {
12 |
13 | lazy var titleLabel: UILabel = {
14 | let label = UILabel(frame: .zero)
15 | label.textColor = .white
16 | label.font = UIFont.systemFont(ofSize: 16)
17 | return label
18 | }()
19 |
20 | override init(reuseIdentifier: String?) {
21 | super.init(reuseIdentifier: reuseIdentifier)
22 | backgroundColor = .clear
23 | }
24 |
25 | required init?(coder: NSCoder) {
26 | fatalError("")
27 | }
28 |
29 | private var isViewReady = false
30 | override func didMoveToWindow() {
31 | super.didMoveToWindow()
32 | guard !isViewReady else {
33 | return
34 | }
35 | isViewReady = true
36 | constructViewHierarchy()
37 | activateConstraints()
38 | }
39 |
40 | private func constructViewHierarchy() {
41 | contentView.addSubview(titleLabel)
42 | }
43 |
44 | private func activateConstraints() {
45 | titleLabel.snp.makeConstraints { make in
46 | make.leading.top.equalTo(10)
47 | make.trailing.bottom.equalTo(-10)
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/App/Home/SubViews/HomeTableViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HomeTableViewCell.swift
3 | // TRTC-API-Example-Swift
4 | //
5 | // Created by peteryhchen on 2022/6/22.
6 | // Copyright © 2022 Tencent. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import SnapKit
11 |
12 | class HomeTableViewCell: UITableViewCell {
13 |
14 | let containerView: UIView = {
15 | let view = UIView(frame: .zero)
16 | view.backgroundColor = UIColor(red: 52.0/255, green: 184.0/255, blue: 97.0/255, alpha: 1)
17 | return view
18 | }()
19 |
20 | let titleLabel: UILabel = {
21 | let label = UILabel(frame: .zero)
22 | label.textColor = .white
23 | label.backgroundColor = .clear
24 | return label
25 | }()
26 |
27 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
28 | super.init(style: style, reuseIdentifier: reuseIdentifier)
29 | selectionStyle = .none
30 | backgroundColor = .black
31 | }
32 |
33 | required init?(coder: NSCoder) {
34 | fatalError("")
35 | }
36 |
37 | private var isViewReady = false
38 |
39 | override func didMoveToWindow() {
40 | super.didMoveToWindow()
41 | guard !isViewReady else {
42 | return
43 | }
44 | isViewReady = true
45 | constructViewHierarchy()
46 | activateConstraints()
47 | }
48 |
49 | private func constructViewHierarchy() {
50 | contentView.addSubview(containerView)
51 | containerView.addSubview(titleLabel)
52 | }
53 |
54 | private func activateConstraints() {
55 |
56 | titleLabel.snp.makeConstraints { make in
57 | make.leading.top.equalTo(10)
58 | make.trailing.bottom.equalTo(-10)
59 | }
60 |
61 | containerView.snp.makeConstraints { make in
62 | make.leading.equalTo(15)
63 | make.top.equalTo(10)
64 | make.trailing.equalTo(-15)
65 | make.bottom.equalTo(-10)
66 | }
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/App/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSAppTransportSecurity
6 |
7 | NSAllowsArbitraryLoads
8 |
9 |
10 | NSPhotoLibraryUsageDescription
11 | 需要访问你的相册权限,开启后才能编辑视频文件
12 | UIApplicationSceneManifest
13 |
14 | UIApplicationSupportsMultipleScenes
15 |
16 | UISceneConfigurations
17 |
18 | UIWindowSceneSessionRoleApplication
19 |
20 |
21 | UISceneConfigurationName
22 | Default Configuration
23 | UISceneDelegateClassName
24 | $(PRODUCT_MODULE_NAME).SceneDelegate
25 | UISceneStoryboardFile
26 | Main
27 |
28 |
29 |
30 |
31 | UIBackgroundModes
32 |
33 | audio
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/App/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // TRTC-API-Example-Swift
4 | //
5 | // Created by peteryhchen on 2022/6/17.
6 | //
7 |
8 | import UIKit
9 |
10 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
11 |
12 | var window: UIWindow?
13 |
14 |
15 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
16 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
17 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
18 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
19 | guard let _ = (scene as? UIWindowScene) else { return }
20 | }
21 |
22 | func sceneDidDisconnect(_ scene: UIScene) {
23 | // Called as the scene is being released by the system.
24 | // This occurs shortly after the scene enters the background, or when its session is discarded.
25 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
26 | // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
27 | }
28 |
29 | func sceneDidBecomeActive(_ scene: UIScene) {
30 | // Called when the scene has moved from an inactive state to an active state.
31 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
32 | }
33 |
34 | func sceneWillResignActive(_ scene: UIScene) {
35 | // Called when the scene will move from an active state to an inactive state.
36 | // This may occur due to temporary interruptions (ex. an incoming phone call).
37 | }
38 |
39 | func sceneWillEnterForeground(_ scene: UIScene) {
40 | // Called as the scene transitions from the background to the foreground.
41 | // Use this method to undo the changes made on entering the background.
42 | }
43 |
44 | func sceneDidEnterBackground(_ scene: UIScene) {
45 | // Called as the scene transitions from the foreground to the background.
46 | // Use this method to save data, release shared resources, and store enough scene-specific state information
47 | // to restore the scene back to its current state.
48 | }
49 |
50 |
51 | }
52 |
53 |
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/Basic/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tencent-RTC/TRTC_iOS/ff2c8291d9f408269d19e5b30f7e4c56463210ea/TRTC-API-Example-Swift/Basic/.gitkeep
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/Basic/Live/LiveAudienceViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LiveAudienceViewController.swift
3 | // TRTC-API-Example-Swift
4 | //
5 | // Created by janejntang on 2022/6/30.
6 | // Copyright © 2022 Tencent. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 | import TXLiteAVSDK_TRTC
12 |
13 | /*
14 | Interactive Live Video Streaming - Audience
15 | The TRTC app supports interactive live video streaming.
16 | This document shows how to integrate the interactive live video streaming feature.
17 | 1. Enter a room: trtcCloud.enterRoom(params, appScene: .LIVE)
18 | 2. Display the video of a remote user: trtcCloud.startRemoteView(userId, streamType: .big, view: view)
19 | 3. Mute a remote user: trtcCloud.muteRemoteAudio(userId as! String, mute: muteButton.isSelected)
20 | Documentation: https://cloud.tencent.com/document/product/647/43181
21 | */
22 | class LiveAudienceViewController:UIViewController {
23 |
24 | let trtcCloud = TRTCCloud()
25 | var roomId: Int = 0
26 | var userId: String = ""
27 |
28 | let audienceLabel :UILabel = {
29 | let lable = UILabel(frame: .zero)
30 | lable.textColor = .white
31 | lable.text = Localize("TRTC-API-Example.LiveAudience.Operating")
32 | lable.adjustsFontSizeToFitWidth = true
33 | return lable
34 | }()
35 |
36 | let muteButton: UIButton = {
37 | let button = UIButton(frame: .zero)
38 | button.setTitle(Localize("TRTC-API-Example.LiveAudience.mute"), for: .normal)
39 | button.setTitle(Localize("TRTC-API-Example.LiveAudience.muteoff"), for: .selected)
40 | button.backgroundColor = .green
41 | button.setTitleColor(.white, for: .normal)
42 | button.titleLabel?.adjustsFontSizeToFitWidth = true
43 | return button
44 | }()
45 |
46 | let anchorUserIdSet:NSMutableOrderedSet = {
47 | let set = type(of: NSMutableOrderedSet()).init(capacity: maxRemoteUserNum)
48 | return set
49 | }()
50 |
51 | override func viewDidLoad() {
52 | super.viewDidLoad()
53 | view.backgroundColor = .black
54 | setupDefaultUIConfig()
55 | activateConstraints()
56 | bindInteraction()
57 | onEnterRoom()
58 | }
59 |
60 | func onEnterRoom() {
61 | let params = TRTCParams()
62 | params.sdkAppId = UInt32(SDKAppID)
63 | params.roomId = UInt32(roomId)
64 | params.userId = userId
65 | params.role = .audience
66 | params.userSig = GenerateTestUserSig.genTestUserSig(identifier: userId) as String
67 |
68 | trtcCloud.delegate = self
69 | trtcCloud.enterRoom(params, appScene: .LIVE)
70 | }
71 |
72 | deinit {
73 | trtcCloud.stopLocalPreview()
74 | trtcCloud.stopLocalAudio()
75 | trtcCloud.exitRoom()
76 | TRTCCloud.destroySharedIntance()
77 | }
78 |
79 | private func setupDefaultUIConfig(){
80 | view.addSubview(audienceLabel)
81 | view.addSubview(muteButton)
82 | }
83 |
84 | //layout
85 | private func activateConstraints() {
86 | audienceLabel.snp.makeConstraints { make in
87 | make.width.equalTo(200)
88 | make.height.equalTo(30)
89 | make.top.equalTo(view.snp.bottom).offset(-100)
90 | make.left.equalTo(20)
91 | }
92 |
93 | muteButton.snp.makeConstraints { make in
94 | make.width.equalTo(70)
95 | make.height.equalTo(30)
96 | make.top.equalTo(audienceLabel.snp.bottom).offset(10)
97 | make.left.equalTo(audienceLabel)
98 | }
99 | }
100 |
101 | //Bind
102 | private func bindInteraction() {
103 | muteButton.addTarget(self, action: #selector(clickmuteButton), for: .touchUpInside)
104 | }
105 |
106 | @objc func clickmuteButton() {
107 |
108 | muteButton.isSelected = !muteButton.isSelected
109 | let index = 0
110 | for userId in anchorUserIdSet{
111 | if index >= maxRemoteUserNum{
112 | return
113 | }
114 | trtcCloud.muteRemoteAudio(userId as! String, mute: muteButton.isSelected)
115 | }
116 | }
117 |
118 | }
119 |
120 | extension LiveAudienceViewController : TRTCCloudDelegate {
121 | func onUserVideoAvailable(_ userId: String, available: Bool) {
122 | let index = anchorUserIdSet.index(of: userId)
123 | if available{
124 | trtcCloud.startRemoteView(userId, streamType: .big, view: view)
125 | if index != NSNotFound {
126 | return
127 | }
128 | anchorUserIdSet.add(userId)
129 | }else{
130 | trtcCloud.stopRemoteView(userId, streamType: .big)
131 | if (index != 0){
132 | anchorUserIdSet.remove(userId)
133 | }
134 | }
135 | }
136 | }
137 |
138 |
139 |
140 |
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/Basic/ScreenShare/ScreenAudienceViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ScreenAudienceViewController.swift
3 | // TRTC-API-Example-Swift
4 | //
5 | // Created by janejntang on 2022/6/27.
6 | // Copyright © 2022 Tencent. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 | import TXLiteAVSDK_TRTC
12 |
13 | /*
14 | Screen Recording Live Streaming
15 | The TRTC app supports screen recording live streaming.
16 | This document shows how to integrate the screen recording live streaming feature.
17 | 1. Enter a room: trtcCloud.enterRoom(params, appScene: .LIVE)
18 | 2. Display the video of a remote user: trtcCloud.startRemoteView(userId, streamType: .big, view: view)
19 | Documentation: https://cloud.tencent.com/document/product/647/45750
20 | */
21 | class ScreenAudienceViewController : UIViewController,TRTCCloudDelegate {
22 |
23 | var roomId : UInt32 = 0
24 | var userId : String = ""
25 | let trtcCloud = TRTCCloud.sharedInstance()
26 |
27 | let remoteView:UIView = {
28 | let view = UIView(frame: .zero)
29 | return view
30 | }()
31 |
32 | override func viewDidLoad() {
33 | super.viewDidLoad()
34 | view.backgroundColor = .black
35 | title = Localize("TRTC-API-Example.ScreenAudience.Title").appending(String(roomId))
36 | view.addSubview(remoteView)
37 | trtcCloud.delegate = self
38 | setupTRTCCloud()
39 | activateConstraints()
40 | }
41 |
42 | private func setupTRTCCloud() {
43 | let params = TRTCParams()
44 | params.sdkAppId = UInt32(SDKAppID)
45 | params.roomId = UInt32(roomId)
46 | params.userId = userId
47 | params.role = .audience
48 | params.userSig = GenerateTestUserSig.genTestUserSig(identifier: userId) as String
49 |
50 | trtcCloud.startLocalAudio(.music)
51 | trtcCloud.enterRoom(params, appScene: .videoCall)
52 | }
53 |
54 | func activateConstraints() {
55 | remoteView.snp.makeConstraints { make in
56 | make.top.left.right.width.equalTo(view)
57 | }
58 | }
59 |
60 | func onUserAudioAvailable(_ userId: String, available: Bool) {
61 | if available{
62 | remoteView.isHidden = false
63 | trtcCloud.startRemoteView(userId, streamType: .big, view: remoteView)
64 | }else{
65 | remoteView.isHidden = true
66 | }
67 | }
68 |
69 | deinit {
70 | trtcCloud.exitRoom()
71 | TRTCCloud.destroySharedIntance()
72 | }
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/Basic/ScreenShare/TRTCBroadcastExtensionLauncher.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TRTCBroadcastExtensionLauncher.swift
3 | // TRTC-API-Example-Swift
4 | //
5 | // Created by janejntang on 2022/6/27.
6 | // Copyright © 2022 Tencent. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import ReplayKit
11 | /*
12 | Screen Recording Live Streaming
13 | The TRTC app supports screen recording live streaming.
14 | This document shows how to integrate the screen recording live streaming feature.
15 | 1. RPSystemBroadcastPickerView enable app screen recoding function : let picker =
16 | RPSystemBroadcastPickerView(frame: CGRect(x: 0, y: 0, width: 44, height: 44))
17 | 2. Set preferredExtension:picker:picker.preferredExtension = bundle.bundleIdentifier
18 | Documentation: https://cloud.tencent.com/document/product/647/45750
19 | */
20 | @available(iOS 12.0, *)
21 | class TRTCBroadcastExtensionLauncher: NSObject {
22 |
23 | var systemBroacastExtensionPicker = RPSystemBroadcastPickerView()
24 | var prevLaunchEventTime : CFTimeInterval = 0
25 |
26 | static let sharedInstance = TRTCBroadcastExtensionLauncher()
27 |
28 | override init() {
29 | super.init()
30 | let picker = RPSystemBroadcastPickerView(frame: CGRect(x: 0, y: 0, width: 44, height: 44))
31 | picker.showsMicrophoneButton = false
32 | picker.autoresizingMask = [.flexibleTopMargin, .flexibleRightMargin]
33 | systemBroacastExtensionPicker = picker
34 |
35 | if let pluginPath = Bundle.main.builtInPlugInsPath,
36 | let contents = try? FileManager.default.contentsOfDirectory(atPath: pluginPath) {
37 |
38 | for content in contents where content.hasSuffix(".appex") {
39 | guard let bundle = Bundle(path: URL(fileURLWithPath: pluginPath).appendingPathComponent(content).path),
40 | let identifier : String = (bundle.infoDictionary?["NSExtension"] as? [String:Any])? ["NSExtensionPointIdentifier"] as? String
41 | else {
42 | continue
43 | }
44 | if identifier == "com.apple.broadcast-services-upload" {
45 | picker.preferredExtension = bundle.bundleIdentifier
46 | break
47 | }
48 | }
49 | }
50 | }
51 |
52 | static func launch() {
53 | TRTCBroadcastExtensionLauncher.sharedInstance.launch()
54 | }
55 |
56 | func launch() {
57 | // The pop-up on iOS 12 is slow and will crash if you click quickly.
58 | let now = CFAbsoluteTimeGetCurrent()
59 | if now - prevLaunchEventTime < 1.0 {
60 | return
61 | }
62 | prevLaunchEventTime = now
63 |
64 | for view in systemBroacastExtensionPicker.subviews {
65 | if let button = view as? UIButton {
66 | button.sendActions(for: .allTouchEvents)
67 | break
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/Debug/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tencent-RTC/TRTC_iOS/ff2c8291d9f408269d19e5b30f7e4c56463210ea/TRTC-API-Example-Swift/Debug/.gitkeep
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/README-zh_CN.md:
--------------------------------------------------------------------------------
1 | # TRTC API-Example
2 | _中文 | [English](README.md)_
3 |
4 | ## 前言
5 | 这个开源示例Demo主要演示了 [TRTC 实时音视频 SDK](https://cloud.tencent.com/document/product/647/32689) 部分API的使用示例,帮助开发者可以更好的理解 TRTC 实时音视频 SDK 的API,从而快速实现一些音视频场景的基本功能。
6 |
7 | ## 结构说明
8 | 在这个示例项目中包含了以下场景:(带上对应的跳转目录,方便用户快速浏览感兴趣的功能)
9 |
10 | - 基础功能
11 | - [语音通话](./Basic/AudioCall)
12 | - [视频通话](./Basic/VideoCall)
13 | - [视频互动直播](./Basic/Live)
14 | - [语音互动直播](./Basic/VoiceChatRoom)
15 | - [录屏直播](./Basic/ScreenShare)
16 | - 进阶功能
17 | - [字符串房间号](./Advanced/StringRoomId)
18 | - [画质设定](./Advanced/SetVideoQuality)
19 | - [音质设定](./Advanced/SetAudioQuality)
20 | - [渲染控制](./Advanced/SetRenderParams)
21 | - [网络测速](./Advanced/SpeedTest)
22 | - [CDN发布](./Advanced/PushCDN)
23 | - [自定义视频采集&渲染](./Advanced/CustomCamera)
24 | - [设置音效](./Advanced/SetAudioEffect)
25 | - [设置背景音乐](./Advanced/SetBackgroundMusic)
26 | - [本地视频文件分享](./Advanced/LocalVideoShare)
27 | - [本地视频录制](./Advanced/LocalRecord)
28 | - [加入多个房间](./Advanced/JoinMultipleRoom)
29 | - [收发SEI消息](./Advanced/SEIMessage)
30 | - [快速切换房间](./Advanced/SwitchRoom)
31 | - [跨房PK](./Advanced/RoomPk)
32 | - [第三方美颜](./Advanced/ThirdBeauty)
33 | - [画中画功能](./Advanced/PictureInPicture)
34 |
35 |
36 | ## 环境准备
37 | - Xcode 11.0及以上版本
38 | - 请确保您的项目已设置有效的开发者签名
39 |
40 |
41 | ## 运行示例
42 |
43 | ### 前提条件
44 | 您已 [注册腾讯云](https://cloud.tencent.com/document/product/378/17985) 账号,并完成 [实名认证](https://cloud.tencent.com/document/product/378/3629)。
45 |
46 |
47 | ### 申请 SDKAPPID 和 SDKSECRETKEY
48 | 1. 登录实时音视频控制台,选择【开发辅助】>【[快速跑通Demo](https://console.cloud.tencent.com/trtc/quickstart)】。
49 | 2. 单击【立即开始】,输入您的应用名称,例如`TestTRTC`,单击【创建应用】。
50 |
51 | 
52 | 3. 创建应用完成后,单击【我已下载,下一步】,可以查看 SDKAppID 和密钥信息。
53 |
54 |
55 | ### 配置 Demo 工程文件
56 | 1. 打开 Debug 目录下的 [GenerateTestUserSig.h](debug/GenerateTestUserSig.h) 文件。
57 | 2. 配置`GenerateTestUserSig.h`文件中的两个参数:
58 | - SDKAPPID:替换该变量值为上一步骤中在页面上看到的 SDKAppID。
59 | - SDKSECRETKEY:替换该变量值为上一步骤中在页面上看到的密钥。
60 | 
61 |
62 | 4. 返回实时音视频控制台,单击【粘贴完成,下一步】。
63 | 5. 单击【关闭指引,进入控制台管理应用】。
64 |
65 | >!本文提到的生成 UserSig 的方案是在客户端代码中配置 SDKSECRETKEY,该方法中 SDKSECRETKEY 很容易被反编译逆向破解,一旦您的密钥泄露,攻击者就可以盗用您的腾讯云流量,因此**该方法仅适合本地跑通 Demo 和功能调试**。
66 | >正确的 UserSig 签发方式是将 UserSig 的计算代码集成到您的服务端,并提供面向 App 的接口,在需要 UserSig 时由您的 App 向业务服务器发起请求获取动态 UserSig。更多详情请参见 [服务端生成 UserSig](https://cloud.tencent.com/document/product/647/17275#Server)。
67 |
68 | ### 配置CDN 相关(可选)
69 | 如果您需要使用CDN相关业务,比如主播使用TRTC SDK互动连麦,观众端播放CDN流这样的方式,您还需要配置如下三个**直播**相关参数:
70 | - `BIZID`;
71 | - `APPID`;
72 | - `CDN_DOMAIN_NAME`;
73 |
74 | 
75 |
76 | 详细操作可以参考 [实现 CDN 直播观看](https://cloud.tencent.com/document/product/647/16826#.E9.80.82.E7.94.A8.E5.9C.BA.E6.99.AF)
77 |
78 | >注意:
79 | >本文提到的生成 UserSig 的方案是在客户端代码中配置 SDKSECRETKEY,该方法中 SDKSECRETKEY 很容易被反编译逆向破解,一旦您的密钥泄露,攻击者就可以盗用您的腾讯云流量,因此**该方法仅适合本地跑通 Demo 和功能调试**。
80 | >正确的 UserSig 签发方式请参见 [服务端生成 UserSig](https://cloud.tencent.com/document/product/647/17275#Server)。
81 |
82 | ### 编译运行
83 | 使用 XCode(11.0及以上的版本)打开源码目录下的 TRTC-API-Example-OC.xcodeproj
84 | > 上述流程并没有解答您的疑问,你可以[点击此处](https://wj.qq.com/s2/8393513/f442/)反馈,我们的**工程师妹子**会尽快处理!
85 |
86 |
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/README.md:
--------------------------------------------------------------------------------
1 | # TRTC API-Example
2 | [中文](README-zh_CN.md) | English
3 |
4 | ## Background
5 | This open-source demo shows how to use some APIs of the [TRTC SDK](https://www.tencentcloud.com/document/product/647/34615) to help you better understand the APIs and use them to implement some basic TRTC features.
6 |
7 | ## Contents
8 | This demo covers the following features (click to view the details of a feature):
9 |
10 | - Basic Features
11 | - [Audio Call](./Basic/AudioCall)
12 | - [Video Call](./Basic/VideoCall)
13 | - [Interactive Live Video Streaming](./Basic/Live)
14 | - [Interactive Live Audio Streaming](./Basic/VoiceChatRoom)
15 | - [Screen Sharing Live Streaming](./Basic/ScreenShare)
16 | - Advanced Features
17 | - [String-type Room IDs](./Advanced/StringRoomId)
18 | - [Video Quality Setting](./Advanced/SetVideoQuality)
19 | - [Audio Quality Setting](./Advanced/SetAudioQuality)
20 | - [Rendering Control](./Advanced/SetRenderParams)
21 | - [Network Speed Testing](./Advanced/SpeedTest)
22 | - [CDN Publishing](./Advanced/PushCDN)
23 | - [Custom Video Capturing & Rendering](./Advanced/CustomCamera)
24 | - [Audio Effect Setting](./Advanced/SetAudioEffect)
25 | - [Background Music Setting](./Advanced/SetBackgroundMusic)
26 | - [Local Video Sharing](./Advanced/LocalVideoShare)
27 | - [Local Video Recording](./Advanced/LocalRecord)
28 | - [Multiple Room Entry](./Advanced/JoinMultipleRoom)
29 | - [SEI Message Receiving/Sending](./Advanced/SEIMessage)
30 | - [Room Switching](./Advanced/SwitchRoom)
31 | - [Cross-Room Competition](./Advanced/RoomPk)
32 | - [Third-Party Beauty Filters](./Advanced/ThirdBeauty)
33 |
34 | ## Environment Requirements
35 | - Xcode 11.0 and above
36 | - Please make sure that your project has set a valid developer signature
37 |
38 |
39 | ## Demo Run Example
40 |
41 | #### Prerequisites
42 | You have [signed up for a Tencent Cloud account](https://intl.cloud.tencent.com/document/product/378/17985) and completed [identity verification](https://intl.cloud.tencent.com/document/product/378/3629).
43 |
44 |
45 | ### Obtaining `SDKAPPID` and `SDKSECRETKEY`
46 | 1. Log in to the TRTC console and select **Application Management** > **[Create application](https://console.tencentcloud.com/trtc/app/create)**.
47 | 2. Enter an application name such as `TestTRTC`, and click **Next**.
48 |
49 | 
50 | 3. Click **Next** to view your `SDKAppID` and key.
51 |
52 |
53 | ### Configuring demo project files
54 | 1. Open the [GenerateTestUserSig.h](debug/GenerateTestUserSig.h) file in the Debug directory.
55 | 2. Configure two parameters in the `GenerateTestUserSig.h` file:
56 | - `SDKAPPID`: `PLACEHOLDER` by default. Set it to the actual `SDKAppID`.
57 | - `SDKSECRETKEY`: left empty by default. Set it to the actual key.
58 | 
59 |
60 | 3. Return to the TRTC console and click **Next**.
61 | 4. Click **Return to Overview Page**.
62 |
63 | >!The method for generating `UserSig` described in this document involves configuring `SDKSECRETKEY` in client code. In this method, `SDKSECRETKEY` may be easily decompiled and reversed, and if your key is disclosed, attackers can steal your Tencent Cloud traffic. Therefore, **this method is suitable only for the local execution and debugging of the demo**.
64 | >The correct `UserSig` distribution method is to integrate the calculation code of `UserSig` into your server and provide an application-oriented API. When `UserSig` is needed, your application can make a request to the business server for dynamic `UserSig`. For more information, please see [How to Calculate UserSig](https://www.tencentcloud.com/document/product/647/35166).
65 |
66 | ## Configuring CDN parameters (optional)
67 | To use CDN services, which are needed for co-anchoring, CDN playback, etc., you need to configure three **live streaming** parameters.
68 |
69 | For detailed instructions, see [CDN Relayed Live Streaming](https://www.tencentcloud.com/document/product/647/47858).
70 |
71 |
72 | ### Compiling and running the project
73 | Use XCode (11.0 and above) to open TRTC-API-Example-OC.xcodeproj in the source directory
74 |
75 |
76 | ## Contact Us
77 | - If you have questions, see [FAQs](https://www.tencentcloud.com/document/product/647/36057).
78 |
79 | - To learn about how the TRTC SDK can be used in different scenarios, see [Sample Code](https://www.tencentcloud.com/document/product/647/42963).
80 |
81 | - For complete API documentation, see [SDK API Documentation](https://www.tencentcloud.com/document/product/647/35119).
82 |
83 | - Communication & Feedback
84 | Welcome to join our Telegram Group to communicate with our professional engineers! We are more than happy to hear from you~
85 | Click to join: [https://t.me/+EPk6TMZEZMM5OGY1](https://t.me/+EPk6TMZEZMM5OGY1)
86 | Or scan the QR code
87 |
88 |
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/Resource/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/Resource/Assets.xcassets/AppIcon.appiconset/AppIcon1024x1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tencent-RTC/TRTC_iOS/ff2c8291d9f408269d19e5b30f7e4c56463210ea/TRTC-API-Example-Swift/Resource/Assets.xcassets/AppIcon.appiconset/AppIcon1024x1024.png
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/Resource/Assets.xcassets/AppIcon.appiconset/AppIcon120x120-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tencent-RTC/TRTC_iOS/ff2c8291d9f408269d19e5b30f7e4c56463210ea/TRTC-API-Example-Swift/Resource/Assets.xcassets/AppIcon.appiconset/AppIcon120x120-1.png
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/Resource/Assets.xcassets/AppIcon.appiconset/AppIcon120x120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tencent-RTC/TRTC_iOS/ff2c8291d9f408269d19e5b30f7e4c56463210ea/TRTC-API-Example-Swift/Resource/Assets.xcassets/AppIcon.appiconset/AppIcon120x120.png
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/Resource/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "2x",
6 | "size" : "20x20"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "3x",
11 | "size" : "20x20"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "29x29"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "3x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "40x40"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "40x40"
32 | },
33 | {
34 | "filename" : "AppIcon120x120-1.png",
35 | "idiom" : "iphone",
36 | "scale" : "2x",
37 | "size" : "60x60"
38 | },
39 | {
40 | "idiom" : "iphone",
41 | "scale" : "3x",
42 | "size" : "60x60"
43 | },
44 | {
45 | "idiom" : "ipad",
46 | "scale" : "1x",
47 | "size" : "20x20"
48 | },
49 | {
50 | "idiom" : "ipad",
51 | "scale" : "2x",
52 | "size" : "20x20"
53 | },
54 | {
55 | "idiom" : "ipad",
56 | "scale" : "1x",
57 | "size" : "29x29"
58 | },
59 | {
60 | "idiom" : "ipad",
61 | "scale" : "2x",
62 | "size" : "29x29"
63 | },
64 | {
65 | "idiom" : "ipad",
66 | "scale" : "1x",
67 | "size" : "40x40"
68 | },
69 | {
70 | "idiom" : "ipad",
71 | "scale" : "2x",
72 | "size" : "40x40"
73 | },
74 | {
75 | "idiom" : "ipad",
76 | "scale" : "1x",
77 | "size" : "76x76"
78 | },
79 | {
80 | "idiom" : "ipad",
81 | "scale" : "2x",
82 | "size" : "76x76"
83 | },
84 | {
85 | "idiom" : "ipad",
86 | "scale" : "2x",
87 | "size" : "83.5x83.5"
88 | },
89 | {
90 | "idiom" : "ios-marketing",
91 | "scale" : "1x",
92 | "size" : "1024x1024"
93 | }
94 | ],
95 | "info" : {
96 | "author" : "xcode",
97 | "version" : 1
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/Resource/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/Resource/Assets.xcassets/audiocall_user_portrait.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "audiocall_user_portrait.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "audiocall_user_portrait-1.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/Resource/Assets.xcassets/audiocall_user_portrait.imageset/audiocall_user_portrait-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tencent-RTC/TRTC_iOS/ff2c8291d9f408269d19e5b30f7e4c56463210ea/TRTC-API-Example-Swift/Resource/Assets.xcassets/audiocall_user_portrait.imageset/audiocall_user_portrait-1.png
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/Resource/Assets.xcassets/audiocall_user_portrait.imageset/audiocall_user_portrait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tencent-RTC/TRTC_iOS/ff2c8291d9f408269d19e5b30f7e4c56463210ea/TRTC-API-Example-Swift/Resource/Assets.xcassets/audiocall_user_portrait.imageset/audiocall_user_portrait.png
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/Resource/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/Resource/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/Resource/Localized/Localize/Localized.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Localized.swift
3 | // TRTC-API-Example-Swift
4 | //
5 | // Created by janejntang on 2022/6/27.
6 | // Copyright © 2022 Tencent. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | func Localize(_ key:String) -> String{
12 | let Localize_TableName = "Localized"
13 | let str = Bundle.main.localizedString(forKey: key, value:"", table:Localize_TableName)
14 | return str
15 | }
16 |
17 | func LocalizeReplace(_ origin:String,_ xxx_replace:String) -> String{
18 | var xxxx_replace = xxx_replace
19 | if xxx_replace == nil{
20 | xxxx_replace = ""
21 | }
22 | return origin.replacingOccurrences(of: "xxx", with: xxxx_replace)
23 | }
24 |
25 | func LocalizeReplaceTwoCharacter(origin:String,xxx_replace:String,yyy_replace:String)->String{
26 | var yyyy_replace = xxx_replace
27 | if yyy_replace == nil{
28 | yyyy_replace = ""
29 | }
30 | return LocalizeReplace(Localize(origin), xxx_replace).replacingOccurrences(of: "yyy", with: yyy_replace)
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/Resource/Localized/Localize/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /*
2 | InfoPlist.strings
3 | TRTC-API-Example-OC
4 |
5 | Created by adams on 2021/4/26.
6 |
7 | */
8 |
9 | "CFBundleDisplayName" = "TRTC-API-Example";
10 | "NSCameraUsageDescription" = "TRTC-API-Example 需要访问你的相机权限,开启后录制的视频才会有画面";
11 | "NSMicrophoneUsageDescription" = "TRTC-API-Example 需要访问你的麦克风权限,开启后录制的视频才会有声音";
12 | "NSPhotoLibraryAddUsageDescription" = "TRTC-API-Example 需要访问你的相册权限,开启后才能保存编辑的文件";
13 | "NSPhotoLibraryUsageDescription" = "TRTC-API-Example 需要访问你的相册权限,开启后才能编辑视频文件";
14 |
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/Resource/Localized/Localize/zh-Hans.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /*
2 | InfoPlist.strings
3 | TRTC-API-Example-OC
4 |
5 | Created by adams on 2021/4/26.
6 |
7 | */
8 |
9 | "CFBundleDisplayName" = "TRTC-API-Example";
10 | "NSCameraUsageDescription" = "TRTC-API-Example 需要访问你的相机权限,开启后录制的视频才会有画面";
11 | "NSMicrophoneUsageDescription" = "TRTC-API-Example 需要访问你的麦克风权限,开启后录制的视频才会有声音";
12 | "NSPhotoLibraryAddUsageDescription" = "TRTC-API-Example 需要访问你的相册权限,开启后才能保存编辑的文件";
13 | "NSPhotoLibraryUsageDescription" = "TRTC-API-Example 需要访问你的相册权限,开启后才能编辑视频文件";
14 |
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/TRTC-API-Example-Swift.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/TRTC-API-Example-Swift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/TRTC-API-Example-Swift.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "pins" : [
3 | {
4 | "identity" : "snapkit",
5 | "kind" : "remoteSourceControl",
6 | "location" : "https://github.com/SnapKit/SnapKit.git",
7 | "state" : {
8 | "revision" : "f222cbdf325885926566172f6f5f06af95473158",
9 | "version" : "5.6.0"
10 | }
11 | }
12 | ],
13 | "version" : 2
14 | }
15 |
--------------------------------------------------------------------------------
/TRTC-API-Example-Swift/TRTC-API-Example-Swift.xcodeproj/xcshareddata/xcschemes/TRTC-API-Example-Swift.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
45 |
51 |
52 |
53 |
54 |
58 |
59 |
60 |
61 |
67 |
69 |
75 |
76 |
77 |
78 |
80 |
81 |
84 |
85 |
86 |
--------------------------------------------------------------------------------