Skip to content

Commit 8340b47

Browse files
author
xianing
committed
Merge branch 'dev/3.4.5' of https://github.i.agoralab.co/AgoraIO/API-Examples into dev/3.4.5
2 parents ddbf578 + af2285b commit 8340b47

9 files changed

Lines changed: 252 additions & 14 deletions

File tree

iOS/APIExample/Common/AgoraExtension.swift

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,17 +113,15 @@ extension AgoraAudioScenario {
113113
extension AgoraEncryptionMode {
114114
func description() -> String {
115115
switch self {
116-
case .AES128XTS: return "AES128XTS"
117-
case .AES256XTS: return "AES256XTS"
118-
case .AES128ECB: return "AES128ECB"
119-
case .SM4128ECB: return "SM4128ECB"
116+
case .AES128GCM2: return "AES128GCM2"
117+
case .AES256GCM2: return "AES256GCM2"
120118
default:
121119
return "\(self.rawValue)"
122120
}
123121
}
124122

125123
static func allValues() -> [AgoraEncryptionMode] {
126-
return [.AES128XTS, .AES256XTS, .AES128ECB, .SM4128ECB]
124+
return [.AES128GCM2, .AES256GCM2]
127125
}
128126
}
129127

iOS/APIExample/Examples/Advanced/JoinMultiChannel/JoinMultiChannel.swift

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ class JoinMultiChannelMain: BaseViewController {
105105
let mediaOptions = AgoraRtcChannelMediaOptions()
106106
mediaOptions.autoSubscribeAudio = true
107107
mediaOptions.autoSubscribeVideo = true
108+
mediaOptions.publishLocalAudio = true
109+
mediaOptions.publishLocalVideo = true
108110

109111
// start joining channel
110112
// 1. Users can only see each other after they join the
@@ -116,9 +118,6 @@ class JoinMultiChannelMain: BaseViewController {
116118
channel1?.setClientRole(.broadcaster)
117119
label1.text = channelName1
118120
channel1?.setRtcChannelDelegate(self)
119-
// a channel will only upstream video if you call publish
120-
// there can be only 1 channel upstreaming at the same time, but you can have multiple channel downstreaming
121-
channel1?.publish()
122121
var result = channel1?.join(byToken: nil, info: nil, uid: 0, options: mediaOptions) ?? -1
123122
if result != 0 {
124123
// Usually happens with invalid parameters
@@ -128,10 +127,16 @@ class JoinMultiChannelMain: BaseViewController {
128127
self.showAlert(title: "Error", message: "joinChannel1 call failed: \(result), please check your params")
129128
}
130129

130+
// auto subscribe options after join channel
131+
let mediaOptions2 = AgoraRtcChannelMediaOptions()
132+
mediaOptions2.autoSubscribeAudio = true
133+
mediaOptions2.autoSubscribeVideo = true
134+
mediaOptions2.publishLocalAudio = false
135+
mediaOptions2.publishLocalVideo = false
131136
channel2 = agoraKit.createRtcChannel(channelName2)
132137
label2.text = channelName2
133138
channel2?.setRtcChannelDelegate(self)
134-
result = channel2?.join(byToken: nil, info: nil, uid: 0, options: mediaOptions) ?? -1
139+
result = channel2?.join(byToken: nil, info: nil, uid: 0, options: mediaOptions2) ?? -1
135140
if result != 0 {
136141
// Usually happens with invalid parameters
137142
// Error code description can be found at:

iOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,12 @@ extension RTMPStreamingMain: AgoraRtcEngineDelegate {
328328
}
329329
}
330330

331+
func rtcEngine(_ engine: AgoraRtcEngineKit, rtmpStreamingEventWithUrl url: String, eventCode: AgoraRtmpStreamingEvent) {
332+
if(eventCode == .urlAlreadyInUse) {
333+
self.showAlert(title: "Error", message: "The URL is already in Use.")
334+
}
335+
}
336+
331337
func rtcEngine(_ engine: AgoraRtcEngineKit, streamPublishedWithUrl url: String, errorCode: AgoraErrorCode) {
332338
if(errorCode == AgoraErrorCode.noError){
333339
retried = 0

iOS/APIExample/Examples/Advanced/StreamEncryption/StreamEncryption.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class StreamEncryptionEntry : UIViewController
1515
@IBOutlet weak var channelTextField: UITextField!
1616
@IBOutlet weak var encryptSecretField: UITextField!
1717
@IBOutlet weak var encryptModeBtn: UIButton!
18-
var mode:AgoraEncryptionMode = .AES128XTS
18+
var mode:AgoraEncryptionMode = .AES128GCM2
1919
var useCustom:Bool = false
2020
let identifier = "StreamEncryption"
2121

@@ -110,6 +110,7 @@ class StreamEncryptionMain: BaseViewController {
110110
let config = AgoraEncryptionConfig()
111111
config.encryptionMode = mode
112112
config.encryptionKey = secret
113+
config.encryptionKdfSalt = getEncryptionSaltFromServer()
113114
let ret = agoraKit.enableEncryption(true, encryptionConfig: config)
114115
if ret != 0 {
115116
// for errors please take a look at:
@@ -157,6 +158,11 @@ class StreamEncryptionMain: BaseViewController {
157158
}
158159
}
159160

161+
func getEncryptionSaltFromServer() -> Data {
162+
163+
return "EncryptionKdfSaltInBase64Strings".data(using: .utf8)!
164+
}
165+
160166
override func willMove(toParent parent: UIViewController?) {
161167
if parent == nil {
162168
// leave channel when exiting the view
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
//
2+
// AudioFrameCriticalSection.h
3+
// Agora-Screen-Sharing-iOS-Broadcast
4+
//
5+
// Created by GongYuhua on 16/11/19.
6+
// Copyright © 2016年 Agora. All rights reserved.
7+
//
8+
9+
#ifndef AGDCAudioFrameCriticalSection_h
10+
#define AGDCAudioFrameCriticalSection_h
11+
12+
#include <pthread.h>
13+
14+
class CriticalSectionWrapper {
15+
public:
16+
// Factory method, constructor disabled
17+
static CriticalSectionWrapper* CreateCriticalSection();
18+
19+
virtual ~CriticalSectionWrapper() {}
20+
21+
// Tries to grab lock, beginning of a critical section. Will wait for the
22+
// lock to become available if the grab failed.
23+
virtual void Enter() = 0;
24+
25+
// Returns a grabbed lock, end of critical section.
26+
virtual void Leave() = 0;
27+
};
28+
29+
// RAII extension of the critical section. Prevents Enter/Leave mismatches and
30+
// provides more compact critical section syntax.
31+
class CriticalSectionScoped {
32+
public:
33+
explicit CriticalSectionScoped(CriticalSectionWrapper* critsec)
34+
: ptr_crit_sec_(critsec) {
35+
ptr_crit_sec_->Enter();
36+
}
37+
38+
~CriticalSectionScoped() {
39+
if (ptr_crit_sec_) {
40+
Leave();
41+
}
42+
}
43+
44+
private:
45+
void Leave() {
46+
ptr_crit_sec_->Leave();
47+
ptr_crit_sec_ = 0;
48+
}
49+
50+
CriticalSectionWrapper* ptr_crit_sec_;
51+
};
52+
53+
class CriticalSectionPosix : public CriticalSectionWrapper {
54+
public:
55+
// CriticalSectionPosix();
56+
//
57+
// virtual ~CriticalSectionPosix();
58+
//
59+
// virtual void Enter() override;
60+
// virtual void Leave() override;
61+
62+
CriticalSectionPosix() {
63+
pthread_mutexattr_t attr;
64+
(void) pthread_mutexattr_init(&attr);
65+
(void) pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
66+
(void) pthread_mutex_init(&mutex_, &attr);
67+
}
68+
69+
~CriticalSectionPosix() {
70+
(void) pthread_mutex_destroy(&mutex_);
71+
}
72+
73+
void
74+
Enter() {
75+
(void) pthread_mutex_lock(&mutex_);
76+
}
77+
78+
void
79+
Leave() {
80+
(void) pthread_mutex_unlock(&mutex_);
81+
}
82+
83+
private:
84+
pthread_mutex_t mutex_;
85+
friend class ConditionVariablePosix;
86+
};
87+
88+
89+
CriticalSectionWrapper* CriticalSectionWrapper::CreateCriticalSection() {
90+
return new CriticalSectionPosix();
91+
}
92+
93+
94+
#endif /* AGDCAudioFrame_hpp */
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//
2+
// AGVideoPreProcessing.h
3+
// Agora-Screen-Sharing-iOS-Broadcast
4+
//
5+
// Created by Alex Zheng on 7/28/16.
6+
// Copyright © 2016 Agora.io All rights reserved.
7+
//
8+
9+
#import <CoreMedia/CoreMedia.h>
10+
#import <AgoraRtcKit/AgoraRtcEngineKit.h>
11+
12+
@interface AgoraAudioProcessing : NSObject
13+
+ (void)registerAudioPreprocessing:(AgoraRtcEngineKit*) kit;
14+
+ (void)deregisterAudioPreprocessing:(AgoraRtcEngineKit*) kit;
15+
+ (void)pushAudioFrame:(unsigned char *)inAudioFrame withFrameSize:(int64_t)frameSize;
16+
@end
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
//
2+
// AGVideoPreProcessing.m
3+
// Agora-Screen-Sharing-iOS-Broadcast
4+
//
5+
// Created by Alex Zheng on 7/28/16.
6+
// Copyright © 2016 Agora.io All rights reserved.
7+
//
8+
9+
#import <Foundation/Foundation.h>
10+
#import <AgoraRtcKit/IAgoraRtcEngine.h>
11+
#import <AgoraRtcKit/IAgoraMediaEngine.h>
12+
#import <string.h>
13+
14+
#import "AgoraAudioProcessing.h"
15+
#import "AgoraAudioCriticalSection.h"
16+
17+
static const int kAudioBufferPoolSize = 48000 * 8;
18+
static unsigned char mRecordingAudioAppPool[kAudioBufferPoolSize];
19+
static int mRecordingAppBufferBytes = 0;
20+
static CriticalSectionWrapper *CritSect = CriticalSectionWrapper::CreateCriticalSection();
21+
22+
void pushAudioAppFrame(unsigned char *inAudioFrame, int64_t frameSize)
23+
{
24+
CriticalSectionScoped lock(CritSect);
25+
26+
int remainedSize = kAudioBufferPoolSize - mRecordingAppBufferBytes;
27+
if (remainedSize >= frameSize) {
28+
memcpy(mRecordingAudioAppPool+mRecordingAppBufferBytes, inAudioFrame, frameSize);
29+
} else {
30+
mRecordingAppBufferBytes = 0;
31+
memcpy(mRecordingAudioAppPool+mRecordingAppBufferBytes, inAudioFrame, frameSize);
32+
}
33+
34+
mRecordingAppBufferBytes += frameSize;
35+
}
36+
37+
class AgoraAudioFrameObserver : public agora::media::IAudioFrameObserver
38+
{
39+
public:
40+
virtual bool onRecordAudioFrame(AudioFrame& audioFrame) override
41+
{
42+
CriticalSectionScoped lock(CritSect);
43+
44+
int bytes = audioFrame.samples * audioFrame.channels * audioFrame.bytesPerSample;
45+
46+
if (mRecordingAppBufferBytes < bytes) {
47+
return false;
48+
}
49+
50+
if (mRecordingAppBufferBytes >= bytes) {
51+
memcpy(audioFrame.buffer, mRecordingAudioAppPool, bytes);
52+
mRecordingAppBufferBytes -= bytes;
53+
memmove(mRecordingAudioAppPool, mRecordingAudioAppPool+bytes, mRecordingAppBufferBytes);
54+
}
55+
56+
return true;
57+
}
58+
59+
virtual bool onPlaybackAudioFrame(AudioFrame& audioFrame) override {
60+
return true;
61+
}
62+
63+
virtual bool onMixedAudioFrame(AudioFrame& audioFrame) override {
64+
return true;
65+
}
66+
67+
virtual bool onPlaybackAudioFrameBeforeMixing(unsigned int uid, AudioFrame& audioFrame) override {
68+
return true;
69+
}
70+
};
71+
72+
static AgoraAudioFrameObserver s_audioFrameObserver;
73+
74+
@implementation AgoraAudioProcessing
75+
+ (void)registerAudioPreprocessing: (AgoraRtcEngineKit*) kit
76+
{
77+
if (!kit) {
78+
return;
79+
}
80+
agora::rtc::IRtcEngine* rtc_engine = (agora::rtc::IRtcEngine*)kit.getNativeHandle;
81+
agora::util::AutoPtr<agora::media::IMediaEngine> mediaEngine;
82+
mediaEngine.queryInterface(rtc_engine, agora::AGORA_IID_MEDIA_ENGINE);
83+
if (mediaEngine) {
84+
mediaEngine->registerAudioFrameObserver(&s_audioFrameObserver);
85+
}
86+
}
87+
88+
+ (void)deregisterAudioPreprocessing:(AgoraRtcEngineKit*)kit
89+
{
90+
if (!kit) {
91+
return;
92+
}
93+
94+
agora::rtc::IRtcEngine* rtc_engine = (agora::rtc::IRtcEngine*)kit.getNativeHandle;
95+
agora::util::AutoPtr<agora::media::IMediaEngine> mediaEngine;
96+
mediaEngine.queryInterface(rtc_engine, agora::AGORA_IID_MEDIA_ENGINE);
97+
if (mediaEngine) {
98+
mediaEngine->registerAudioFrameObserver(NULL);
99+
}
100+
}
101+
102+
+ (void)pushAudioFrame:(unsigned char *)inAudioFrame withFrameSize:(int64_t)frameSize
103+
{
104+
pushAudioAppFrame(inAudioFrame, frameSize);
105+
}
106+
107+
@end

macOS/APIExample/Examples/Advanced/JoinMultiChannel/JoinMultiChannel.swift

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ class JoinMultipleChannel: BaseViewController {
4949
let mediaOptions = AgoraRtcChannelMediaOptions()
5050
mediaOptions.autoSubscribeAudio = true
5151
mediaOptions.autoSubscribeVideo = true
52+
mediaOptions.publishLocalAudio = false
53+
mediaOptions.publishLocalVideo = false
5254

5355
var channel: AgoraRtcChannel?
5456
if channel1 == nil {
@@ -77,7 +79,8 @@ class JoinMultipleChannel: BaseViewController {
7779
if isPublished && channelName == selectedChannel {
7880
if let channel = getChannelByName(selectedChannel) {
7981
channel.setClientRole(.audience)
80-
channel.unpublish()
82+
channel.muteLocalAudioStream(true)
83+
channel.muteLocalVideoStream(true)
8184
isPublished = false
8285
}
8386
}
@@ -148,7 +151,8 @@ class JoinMultipleChannel: BaseViewController {
148151
if isPublished && channelName == selectedChannel {
149152
if let channel = getChannelByName(selectedChannel) {
150153
channel.setClientRole(.audience)
151-
channel.unpublish()
154+
channel.muteLocalAudioStream(true)
155+
channel.muteLocalVideoStream(true)
152156
isPublished = false
153157
}
154158
}
@@ -187,13 +191,15 @@ class JoinMultipleChannel: BaseViewController {
187191
if !isPublished {
188192
if let channel = getChannelByName(selectedChannel) {
189193
channel.setClientRole(.broadcaster)
190-
channel.publish()
194+
channel.muteLocalAudioStream(false)
195+
channel.muteLocalVideoStream(false)
191196
isPublished = true
192197
}
193198
} else {
194199
if let channel = getChannelByName(selectedChannel) {
195200
channel.setClientRole(.audience)
196-
channel.unpublish()
201+
channel.muteLocalAudioStream(true)
202+
channel.muteLocalVideoStream(true)
197203
isPublished = false
198204
}
199205
}

macOS/APIExample/Resources/bg.jpg

23.6 KB
Loading

0 commit comments

Comments
 (0)