This commit is contained in:
启星
2025-08-12 14:27:12 +08:00
parent 9d18b353b1
commit 1bd5e77c45
8785 changed files with 978163 additions and 2 deletions

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AvailableLibraries</key>
<array>
<dict>
<key>LibraryIdentifier</key>
<string>ios-arm64_armv7</string>
<key>LibraryPath</key>
<string>AgoraRtcKit.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>armv7</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
</dict>
<dict>
<key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string>
<key>LibraryPath</key>
<string>AgoraRtcKit.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
</array>
<key>CFBundlePackageType</key>
<string>XFWK</string>
<key>XCFrameworkFormatVersion</key>
<string>1.0</string>
</dict>
</plist>

View File

@@ -0,0 +1,73 @@
// Copyright (c) 2020 Agora.io. All rights reserved
// This program is confidential and proprietary to Agora.io.
// And may not be copied, reproduced, modified, disclosed to others, published
// or used, in whole or in part, without the express prior written permission
// of Agora.io.
#pragma once
#if defined(_WIN32)
// clang-format off
// clang formating would change include order.
// Include WinSock2.h before including <Windows.h> to maintain consistency with
// win32.h. To include win32.h directly, it must be broken out into its own
// build target.
#include <WinSock2.h>
#include <Windows.h>
// clang-format on
#endif // _WIN32
namespace agora {
class AtomicOps {
public:
#if defined(_WIN32)
// Assumes sizeof(int) == sizeof(LONG), which it is on Win32 and Win64.
static int Increment(volatile int* i) {
return ::InterlockedIncrement(reinterpret_cast<volatile LONG*>(i));
}
static int Decrement(volatile int* i) {
return ::InterlockedDecrement(reinterpret_cast<volatile LONG*>(i));
}
static int AcquireLoad(volatile const int* i) { return *i; }
static void ReleaseStore(volatile int* i, int value) { *i = value; }
static int CompareAndSwap(volatile int* i, int old_value, int new_value) {
return ::InterlockedCompareExchange(reinterpret_cast<volatile LONG*>(i),
new_value, old_value);
}
// Pointer variants.
template <typename T>
static T* AcquireLoadPtr(T* volatile* ptr) {
return *ptr;
}
template <typename T>
static T* CompareAndSwapPtr(T* volatile* ptr, T* old_value, T* new_value) {
return static_cast<T*>(::InterlockedCompareExchangePointer(
reinterpret_cast<PVOID volatile*>(ptr), new_value, old_value));
}
#else
static int Increment(volatile int* i) { return __sync_add_and_fetch(i, 1); }
static int Decrement(volatile int* i) { return __sync_sub_and_fetch(i, 1); }
static int AcquireLoad(volatile const int* i) {
return __atomic_load_n(i, __ATOMIC_ACQUIRE);
}
static void ReleaseStore(volatile int* i, int value) {
__atomic_store_n(i, value, __ATOMIC_RELEASE);
}
static int CompareAndSwap(volatile int* i, int old_value, int new_value) {
return __sync_val_compare_and_swap(i, old_value, new_value);
}
// Pointer variants.
template <typename T>
static T* AcquireLoadPtr(T* volatile* ptr) {
return __atomic_load_n(ptr, __ATOMIC_ACQUIRE);
}
template <typename T>
static T* CompareAndSwapPtr(T* volatile* ptr, T* old_value, T* new_value) {
return __sync_val_compare_and_swap(ptr, old_value, new_value);
}
#endif // _WIN32
};
} // namespace agora

View File

@@ -0,0 +1,36 @@
//
// AgoraRtcEngineKit.h
// AgoraRtcEngineKit
//
// Copyright (c) 2018 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "AgoraConstants.h"
#import "AgoraObjects.h"
/** Agora provides ensured quality of experience (QoE) for worldwide Internet-based voice and video communications through a virtual global network that is especially optimized for real-time web and mobile-to-mobile applications.
The AgoraRtcEngineKit class is the entry point of the Agora SDK that provides simple APIs for applications to easily start voice and video communication.
*/
@class AgoraRtcEngineKit;
@class AgoraMediaRecorder;
@protocol AgoraAudioEncodedFrameDelegate <NSObject>
@required
/**
* Occurs when the record audio data is received.
*/
- (void)onRecordEncodedAudioFrame:(NSData* _Nonnull)frameData info:(AgoraEncodedAudioFrameInfo* _Nonnull)info NS_SWIFT_NAME(onRecordEncodedAudioFrame(_:info:));
/**
* Occurs when the playback audio data is received.
*/
- (void)onPlaybackEncodedAudioFrame:(NSData* _Nonnull)frameData info:(AgoraEncodedAudioFrameInfo* _Nonnull)info NS_SWIFT_NAME(onPlaybackEncodedAudioFrame(_:info:));
/**
* Occurs when the mixed audio data is received.
*/
- (void)onMixedEncodedAudioFrame:(NSData* _Nonnull)frameData info:(AgoraEncodedAudioFrameInfo* _Nonnull)info NS_SWIFT_NAME(onMixedEncodedAudioFrame(_:info:));
@end

View File

@@ -0,0 +1,204 @@
//
// AgoraRtcEngineKit.h
// AgoraRtcEngineKit
//
// Copyright (c) 2018 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "AgoraEnumerates.h"
@class AgoraAudioFrame;
@class AgoraAudioParams;
/**
* The AgoraAudioFrameDelegate protocol enables audio frame callback event notifications to your application.
*/
@protocol AgoraAudioFrameDelegate <NSObject>
@optional
/**
* Occurs when the recorded audio frame is received.
* @param frame A pointer to the audio frame: AgoraAudioFrame.
* @param channelId Unique channel name for the AgoraRTC session in the string
* format. The string length must be less than 64 bytes. Supported character
* scopes are:
* - All lowercase English letters: a to z.
* - All uppercase English letters: A to Z.
* - All numeric characters: 0 to 9.
* - The space character.
* - Punctuation characters and other symbols, including: "!", "#", "$", "%", "&", "(", ")", "+", "-", ":", ";", "<", "=", ".", ">", "?", "@", "[", "]", "^", "_", " {", "}", "|", "~", ",".
* @return
* - true: The recorded audio frame is valid and is encoded and sent.
* - false: The recorded audio frame is invalid and is not encoded or sent.
*/
- (BOOL)onRecordAudioFrame:(AgoraAudioFrame* _Nonnull)frame channelId:(NSString * _Nonnull)channelId NS_SWIFT_NAME(onRecordAudioFrame(_:channelId:));
/**
* Occurs when the playback audio frame is received.
* @param channelId Unique channel name for the AgoraRTC session in the string
* format. The string length must be less than 64 bytes. Supported character
* scopes are:
* - All lowercase English letters: a to z.
* - All uppercase English letters: A to Z.
* - All numeric characters: 0 to 9.
* - The space character.
* - Punctuation characters and other symbols, including: "!", "#", "$", "%", "&", "(", ")", "+", "-", ":", ";", "<", "=", ".", ">", "?", "@", "[", "]", "^", "_", " {", "}", "|", "~", ",".
* @param frame A pointer to the audio frame: AgoraAudioFrame.
* @return
* - true: The playback audio frame is valid and is encoded and sent.
* - false: The playback audio frame is invalid and is not encoded or sent.
*/
- (BOOL)onPlaybackAudioFrame:(AgoraAudioFrame* _Nonnull)frame channelId:(NSString * _Nonnull)channelId NS_SWIFT_NAME(onPlaybackAudioFrame(_:channelId:));
/**
* Occurs when the mixed audio data is received.
* @param frame The A pointer to the audio frame: AgoraAudioFrame.
* @param channelId Unique channel name for the AgoraRTC session in the string
* format. The string length must be less than 64 bytes. Supported character
* scopes are:
* - All lowercase English letters: a to z.
* - All uppercase English letters: A to Z.
* - All numeric characters: 0 to 9.
* - The space character.
* - Punctuation characters and other symbols, including: "!", "#", "$", "%", "&", "(", ")", "+", "-", ":", ";", "<", "=", ".", ">", "?", "@", "[", "]", "^", "_", " {", "}", "|", "~", ",".
* @return
* - true: The mixed audio data is valid and is encoded and sent.
* - false: The mixed audio data is invalid and is not encoded or sent.
*/
- (BOOL)onMixedAudioFrame:(AgoraAudioFrame* _Nonnull)frame channelId:(NSString * _Nonnull)channelId NS_SWIFT_NAME(onMixedAudioFrame(_:channelId:));
/**
* Occurs when the ear monitoring audio frame is received.
* @param frame A pointer to the audio frame: AgoraAudioFrame.
* @return
* - true: The ear monitoring audio frame is valid and is encoded and sent.
* - false: The ear monitoring audio frame is invalid and is not encoded or sent.
*/
- (BOOL)onEarMonitoringAudioFrame:(AgoraAudioFrame* _Nonnull)frame NS_SWIFT_NAME(onEarMonitoringAudioFrame(_:));
/**
Sets the frame position for the audio observer.
* @return A bit mask that controls the frame position of the audio observer.
* @note - Use '|' (the OR operator) to observe multiple frame positions.
* <p>
* After you successfully register the audio observer, the SDK triggers this callback each time it receives a audio frame. You can determine which position to observe by setting the return value.
* The SDK provides 4 positions for observer. Each position corresponds to a callback function:
* - `AgoraAudioFramePositionPlayback (1 << 0)`: The position for playback audio frame is received, which corresponds to the \ref onPlaybackFrame "onPlaybackFrame" callback.
* - `AgoraAudioFramePositionRecord (1 << 1)`: The position for record audio frame is received, which corresponds to the \ref onRecordFrame "onRecordFrame" callback.
* - `AgoraAudioFramePositionMixed (1 << 2)`: The position for mixed audio frame is received, which corresponds to the \ref onMixedFrame "onMixedFrame" callback.
* - `AgoraAudioFramePositionBeforeMixing (1 << 3)`: The position for playback audio frame before mixing is received, which corresponds to the \ref onPlaybackFrameBeforeMixing "onPlaybackFrameBeforeMixing" callback.
* @return The bit mask that controls the audio observation positions.
See AgoraAudioFramePosition.
*/
- (AgoraAudioFramePosition)getObservedAudioFramePosition NS_SWIFT_NAME(getObservedAudioFramePosition());
/** Sets the audio mixing format for the
[onMixedAudioFrame]([AgoraAudioFrameDelegate onMixedAudioFrame:]) callback.
Register the `getMixedAudioParams` callback when calling the
[setAudioFrameDelegate]([AgoraRtcEngineKit setAudioFrameDelegate:]) method. After you
successfully register the audio delegate, the SDK triggers this callback each
time it receives an audio frame. You can set the audio mixing format in
the return value of this callback.
**Note**:
- The SDK calculates the sample interval according to the `AgoraAudioParams`
you set in the return value of this callback and triggers the
`onMixedAudioFrame` callback at the calculated sample interval.
Sample interval (seconds) = `samplesPerCall`/(`sampleRate` × `channel`).
Ensure that the value of sample interval is equal to or greater than 0.01.
@return Sets the audio format. See AgoraAudioParams.
*/
- (AgoraAudioParams* _Nonnull)getMixedAudioParams NS_SWIFT_NAME(getMixedAudioParams());
/** Sets the audio recording format for the
[onRecordAudioFrame]([AgoraAudioFrameDelegate onRecordAudioFrame:])
callback.
Register the `getRecordAudioParams` callback when calling the
[setAudioFrameDelegate]([AgoraRtcEngineKit setAudioFrameDelegate:]) method. After you
successfully register the audio delegate, the SDK triggers this callback each
time it receives an audio frame. You can set the audio recording format in
the return value of this callback.
**Note**:
- This callback applies to iOS only.
- The SDK calculates the sample interval according to the `AgoraAudioParams`
you set in the return value of this callback and triggers the
`onRecordAudioFrame` callback at the calculated sample interval.
Sample interval (seconds) = `samplesPerCall`/(`sampleRate` × `channel`).
Ensure that the value of sample interval is equal to or greater than 0.01.
@return Sets the audio format. See AgoraAudioParams.
*/
- (AgoraAudioParams* _Nonnull)getRecordAudioParams NS_SWIFT_NAME(getRecordAudioParams());
/** Sets the audio playback format for the
[onPlaybackAudioFrame]([AgoraAudioFrameDelegate onPlaybackAudioFrame:])
callback.
Register the `getPlaybackAudioParams` callback when calling the
[setAudioFrameDelegate]([AgoraRtcEngineKit setAudioFrameDelegate:]) method. After you
successfully register the audio delegate, the SDK triggers this callback each
time it receives an audio frame. You can set the audio playback format in
the return value of this callback.
**Note**:
- The SDK calculates the sample interval according to the `AgoraAudioParams`
you set in the return value of this callback and triggers the
`onPlaybackAudioFrame` callback at the calculated sample interval.
Sample interval (seconds) = `samplesPerCall`/(`sampleRate` × `channel`).
Ensure that the value of sample interval is equal to or greater than 0.01.
@return Sets the audio format. See AgoraAudioParams.
*/
- (AgoraAudioParams* _Nonnull)getPlaybackAudioParams NS_SWIFT_NAME(getPlaybackAudioParams());
/** Sets the audio recording format for the
[onEarMonitoringAudioFrame]([AgoraAudioFrameDelegate onEarMonitoringAudioFrame:])
callback.
Register the `getEarMonitoringAudioParams` callback when calling the
[setAudioFrameDelegate]([AgoraRtcEngineKit setAudioFrameDelegate:]) method. After you
successfully register the audio delegate, the SDK triggers this callback each
time it receives an audio frame. You can set the audio recording format in
the return value of this callback.
**Note**:
- This callback applies to iOS only.
- The SDK calculates the sample interval according to the `AgoraAudioParams`
you set in the return value of this callback and triggers the
`onEarMonitoringAudioFrame` callback at the calculated sample interval.
Sample interval (seconds) = `samplesPerCall`/(`sampleRate` × `channel`).
Ensure that the value of sample interval is equal to or greater than 0.01.
@return Sets the audio format. See AgoraAudioParams.
*/
- (AgoraAudioParams* _Nonnull)getEarMonitoringAudioParams NS_SWIFT_NAME(getEarMonitoringAudioParams());
/**
* Occurs when the before-mixing playback audio frame is received.
* @param channelId Unique channel name for the AgoraRTC session in the string
* format. The string length must be less than 64 bytes. Supported character
* scopes are:
* - All lowercase English letters: a to z.
* - All uppercase English letters: A to Z.
* - All numeric characters: 0 to 9.
* - The space character.
* - Punctuation characters and other symbols, including: "!", "#", "$", "%", "&", "(", ")", "+", "-", ":", ";", "<", "=", ".", ">", "?", "@", "[", "]", "^", "_", " {", "}", "|", "~", ",".
* @param uid ID of the remote user.
* @param frame A pointer to the audio frame: AgoraAudioFrame.
* @return
* - true: The before-mixing playback audio frame is valid and is encoded and sent.
* - false: The before-mixing playback audio frame is invalid and is not encoded or sent.
*/
- (BOOL)onPlaybackAudioFrameBeforeMixing:(AgoraAudioFrame* _Nonnull)frame channelId:(NSString * _Nonnull)channelId uid:(NSUInteger)uid NS_SWIFT_NAME(onPlaybackAudioFrame(beforeMixing:channelId:uid:));
@end

View File

@@ -0,0 +1,122 @@
//
// AgoraConstants.h
// AgoraRtcEngineKit
//
// Copyright (c) 2018 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
#elif TARGET_OS_MAC
#import <AppKit/AppKit.h>
#endif
/** The standard bitrate in [setVideoEncoderConfiguration]([AgoraRtcEngineKit setVideoEncoderConfiguration:]).
(Recommended) In a live broadcast, Agora recommends setting a larger bitrate to improve the video quality. When you choose AgoraVideoBitrateStandard, the bitrate value doubles in a live broadcast mode, and remains the same as in AgoraVideoProfile in a communication mode.
*/
extern NSInteger const AgoraVideoBitrateStandard;
/** The compatible bitrate in [setVideoEncoderConfiguration]([AgoraRtcEngineKit setVideoEncoderConfiguration:]).
The bitrate in both the live broadcast and communication modes remain the same as in AgoraVideoProfile.
*/
extern NSInteger const AgoraVideoBitrateCompatible;
/** The min bitrate in [setVideoEncoderConfiguration]([AgoraRtcEngineKit setVideoEncoderConfiguration:]).
The min bitrate set to default value
*/
extern NSInteger const AgoraVideoDefaultMinBitrate;
/** The min bitrate in [setVideoEncoderConfiguration]([AgoraRtcEngineKit setVideoEncoderConfiguration:]).
The min bitrate will be equal to bitrate
*/
extern NSInteger const AgoraVideoMinBitrateEqualToBitrate;
/**
* set analyze duration for real time stream
* @example "setPlayerOption(AgoraRtcMediaPlayerRealTimeStreamAnalyzeDuration,1000000)"
*/
extern NSString* const AgoraRtcMediaPlayerRealTimeStreamAnalyzeDuration;
/**
* make the player to enable audio or not
* @example "setPlayerOption(AgoraRtcMediaPlayerEnableAudio,0)"
*/
extern NSString* const AgoraRtcMediaPlayerEnableAudio;
/**
* make the player to enable video or not
* @example "setPlayerOption(AgoraRtcMediaPlayerEnableVideo,0)"
*/
extern NSString* const AgoraRtcMediaPlayerEnableVideo;
/**
* set the player enable to search metadata
* @example "setPlayerOption(AgoraRtcMediaPlayerEnableSearchMetadata,0)"
*/
extern NSString* const AgoraRtcMediaPlayerEnableSearchMetadata;
/** 120 x 120
*/
extern CGSize const AgoraVideoDimension120x120;
/** 160 x 120
*/
extern CGSize const AgoraVideoDimension160x120;
/** 180 x 180
*/
extern CGSize const AgoraVideoDimension180x180;
/** 240 x 180
*/
extern CGSize const AgoraVideoDimension240x180;
/** 320 x 180
*/
extern CGSize const AgoraVideoDimension320x180;
/** 240 x 240
*/
extern CGSize const AgoraVideoDimension240x240;
/** 320 x 240
*/
extern CGSize const AgoraVideoDimension320x240;
/** 424 x 240
*/
extern CGSize const AgoraVideoDimension424x240;
/** 360 x 360
*/
extern CGSize const AgoraVideoDimension360x360;
/** 480 x 360
*/
extern CGSize const AgoraVideoDimension480x360;
/** 640 x 360
*/
extern CGSize const AgoraVideoDimension640x360;
/** 480 x 480
*/
extern CGSize const AgoraVideoDimension480x480;
/** 640 x 480
*/
extern CGSize const AgoraVideoDimension640x480;
/** 840 x 480
*/
extern CGSize const AgoraVideoDimension840x480;
/** 960 x 540
*/
extern CGSize const AgoraVideoDimension960x540;
/** 960 x 720 (Depends on the hardware)
*/
extern CGSize const AgoraVideoDimension960x720;
/** 1280 x 720 (Depends on the hardware)
*/
extern CGSize const AgoraVideoDimension1280x720;
/** 1920 x 1080 (Depends on the hardware)
*/
extern CGSize const AgoraVideoDimension1920x1080;
/** 25400 x 1440 (Depends on the hardware)
*/
extern CGSize const AgoraVideoDimension2540x1440;
/** 3840 x 2160 (Depends on the hardware)
*/
extern CGSize const AgoraVideoDimension3840x2160;

View File

@@ -0,0 +1,38 @@
//
// AgoraRtcEngineKit.h
// AgoraRtcEngineKit
//
// Copyright (c) 2018 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "AgoraConstants.h"
#import "AgoraObjects.h"
/** Agora provides ensured quality of experience (QoE) for worldwide Internet-based voice and video communications through a virtual global network that is especially optimized for real-time web and mobile-to-mobile applications.
The AgoraRtcEngineKit class is the entry point of the Agora SDK that provides simple APIs for applications to easily start voice and video communication.
*/
@class AgoraRtcEngineKit;
@class AgoraMediaRecorder;
/**
* The event handler for direct cdn streaming
*
*/
@protocol AgoraDirectCdnStreamingEventDelegate <NSObject>
@optional
/**
* Event callback of direct cdn streaming
* @param state Current status
* @param reason Reason Code
* @param message Message
*/
- (void)onDirectCdnStreamingStateChanged:(AgoraDirectCdnStreamingState)state
reason:(AgoraDirectCdnStreamingReason)reason
message:(NSString *_Nullable)message NS_SWIFT_NAME(onDirectCdnStreamingStateChanged(_:reason:message:));
- (void)onDirectCdnStreamingStats:(AgoraDirectCdnStreamingStats *_Nonnull)stats NS_SWIFT_NAME(onDirectCdnStreamingStats(_:));
@end

View File

@@ -0,0 +1,19 @@
//
// AgoraRtcEngineKit.h
// AgoraRtcEngineKit
//
// Copyright (c) 2018 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
@class AgoraEncodedVideoFrameInfo;
@protocol AgoraEncodedVideoFrameDelegate <NSObject>
@optional
/**
* Occurs when get H264 video data interface before decoding
*/
- (BOOL)onEncodedVideoFrameReceived:(NSData * _Nonnull )videoData length:(size_t)length info:(AgoraEncodedVideoFrameInfo * _Nonnull)videoFrameInfo NS_SWIFT_NAME(onEncodedVideoFrameReceived(_:length:info:));
@end

View File

@@ -0,0 +1,77 @@
//
// Copyright (c) 2020 Agora.io. All rights reserved
// This program is confidential and proprietary to Agora.io.
// And may not be copied, reproduced, modified, disclosed to others, published
// or used, in whole or in part, without the express prior written permission
// of Agora.io.
#pragma once // NOLINT(build/header_guard)
#include "NGIAgoraExtensionControl.h"
AGORA_API agora::rtc::IExtensionControl* AGORA_CALL getAgoraExtensionControl();
AGORA_API void AGORA_CALL declareProviderVersion(
const char*, const agora::rtc::ExtensionVersion&);
typedef void(*agora_ext_entry_func_t)(void);
AGORA_API void AGORA_CALL registerProviderEntry(const char*, agora_ext_entry_func_t);
#define DECLARE_CREATE_AND_REGISTER_PROVIDER(PROVIDER_NAME, PROVIDER_CLASS, PROVIDER_INTERFACE_USED, ...) \
static void register_##PROVIDER_NAME##_to_agora() { \
auto control = getAgoraExtensionControl(); \
agora::rtc::ExtensionVersion version = \
agora::rtc::ExtensionInterfaceVersion<PROVIDER_INTERFACE_USED>::Version(); \
declareProviderVersion(#PROVIDER_NAME, version); \
if (#PROVIDER_NAME && control) { \
control->registerProvider(#PROVIDER_NAME, \
new agora::RefCountedObject<PROVIDER_CLASS>(__VA_ARGS__)); \
} \
} \
#define DECLARE_CREATE_AND_REGISTER_PROVIDER_PTR(PROVIDER_NAME, PROVIDER_INTERFACE_USED, PROVIDER_REF_PTR) \
static void register_##PROVIDER_NAME##_to_agora() { \
auto control = getAgoraExtensionControl(); \
agora::rtc::ExtensionVersion version = \
agora::rtc::ExtensionInterfaceVersion<PROVIDER_INTERFACE_USED>::Version(); \
declareProviderVersion(#PROVIDER_NAME, version); \
if (#PROVIDER_NAME && control) { \
control->registerProvider(#PROVIDER_NAME, PROVIDER_REF_PTR); \
} \
} \
#if defined (__GNUC__)
#define REGISTER_AGORA_EXTENSION_PROVIDER(PROVIDER_NAME, PROVIDER_CLASS, PROVIDER_INTERFACE_USED, ...) \
DECLARE_CREATE_AND_REGISTER_PROVIDER(PROVIDER_NAME, PROVIDER_CLASS, PROVIDER_INTERFACE_USED, __VA_ARGS__); \
__attribute__((constructor, used)) \
static void _##PROVIDER_NAME##_provider_entry() { \
registerProviderEntry(#PROVIDER_NAME, register_##PROVIDER_NAME##_to_agora); \
} \
#define REGISTER_AGORA_EXTENSION_PROVIDER_PTR(PROVIDER_NAME, PROVIDER_INTERFACE_USED, PROVIDER_REF_PTR) \
DECLARE_CREATE_AND_REGISTER_PROVIDER_PTR(PROVIDER_NAME, PROVIDER_INTERFACE_USED, PROVIDER_REF_PTR); \
__attribute__((constructor, used)) \
static void _##PROVIDER_NAME##_provider_entry() { \
registerProviderEntry(#PROVIDER_NAME, register_##PROVIDER_NAME##_to_agora); \
} \
#elif defined (_MSC_VER)
#define REGISTER_AGORA_EXTENSION_PROVIDER(PROVIDER_NAME, PROVIDER_CLASS, PROVIDER_INTERFACE_USED, ...) \
DECLARE_CREATE_AND_REGISTER_PROVIDER(PROVIDER_NAME, PROVIDER_CLASS, PROVIDER_INTERFACE_USED, __VA_ARGS__); \
static int _##PROVIDER_NAME##_provider_entry() { \
registerProviderEntry(#PROVIDER_NAME, register_##PROVIDER_NAME##_to_agora); \
return 0; \
} \
const int DUMMY_AGORA_REGEXT_##PROVIDE_NAME##_VAR = _##PROVIDER_NAME##_provider_entry(); \
#define REGISTER_AGORA_EXTENSION_PROVIDER_PTR(PROVIDER_NAME, PROVIDER_INTERFACE_USED, PROVIDER_REF_PTR) \
DECLARE_CREATE_AND_REGISTER_PROVIDER_PTR(PROVIDER_NAME, PROVIDER_INTERFACE_USED, PROVIDER_REF_PTR); \
static int _##PROVIDER_NAME##_provider_entry() { \
registerProviderEntry(#PROVIDER_NAME, register_##PROVIDER_NAME##_to_agora); \
return 0; \
} \
const int DUMMY_AGORA_REGEXT_##PROVIDE_NAME##_VAR = _##PROVIDER_NAME##_provider_entry(); \
#else
#error Unsupported Compilation Toolchain!
#endif

View File

@@ -0,0 +1,111 @@
//
// Copyright (c) 2021 Agora.io. All rights reserved
// This program is confidential and proprietary to Agora.io.
// And may not be copied, reproduced, modified, disclosed to others, published
// or used, in whole or in part, without the express prior written permission
// of Agora.io.
#pragma once
namespace agora {
namespace rtc {
struct ExtensionVersion {
// Extension Framework Version : major.minor.micro
int major_v;
int minor_v;
int micro_v;
ExtensionVersion()
: major_v(0), minor_v(0), micro_v(0) {}
ExtensionVersion(int majorV, int minorV = 0, int microV = 0)
: major_v(majorV), minor_v(minorV), micro_v(microV) {}
bool operator==(const ExtensionVersion& other) const {
return major_v == other.major_v && minor_v == other.minor_v && micro_v == other.micro_v;
}
bool operator>(const ExtensionVersion& other) const {
return major_v > other.major_v || (major_v == other.major_v && minor_v > other.minor_v)
|| (major_v == other.major_v && minor_v == other.minor_v && micro_v > other.micro_v);
}
bool operator<(const ExtensionVersion& other) const {
return major_v < other.major_v || (major_v == other.major_v && minor_v < other.minor_v)
|| (major_v == other.major_v && minor_v == other.minor_v && micro_v < other.micro_v);
}
bool operator<=(const ExtensionVersion& other) const {
return !operator>(other);
}
bool operator>=(const ExtensionVersion& other) const {
return !operator<(other);
}
};
#define BUMP_MAJOR_VERSION(VERSION) \
ExtensionVersion(VERSION.major_v + 1, 0, 0); \
#define BUMP_MINOR_VERSION(VERSION) \
ExtensionVersion(VERSION.major_v, VERSION.minor_v + 1, 0); \
#define BUMP_MICRO_VERSION(VERSION) \
ExtensionVersion(VERSION.major_v, VERSION.minor_v, VERSION.micro_v + 1); \
class IExtensionProvider;
class IExtensionProviderV2;
class IExtensionProviderV3;
class IAudioFilter;
class IAudioFilterV2;
class IExtensionVideoFilter;
class IScreenCaptureSource;
template <class T>
struct ExtensionInterfaceVersion;
template <>
struct ExtensionInterfaceVersion<IExtensionProvider> {
static ExtensionVersion Version() {
return ExtensionVersion(1, 0, 0);
}
};
template <>
struct ExtensionInterfaceVersion<IExtensionProviderV2> {
static ExtensionVersion Version() {
return BUMP_MAJOR_VERSION(ExtensionInterfaceVersion<IExtensionProvider>::Version());
}
};
template <>
struct ExtensionInterfaceVersion<IAudioFilter> {
static ExtensionVersion Version() {
return ExtensionVersion(1, 0, 0);
}
};
template <>
struct ExtensionInterfaceVersion<IAudioFilterV2> {
static ExtensionVersion Version() {
return BUMP_MAJOR_VERSION(ExtensionInterfaceVersion<IAudioFilter>::Version());
}
};
template <>
struct ExtensionInterfaceVersion<IExtensionVideoFilter> {
static ExtensionVersion Version() {
return ExtensionVersion(1, 0, 0);
}
};
template <>
struct ExtensionInterfaceVersion<IScreenCaptureSource> {
static ExtensionVersion Version() {
return ExtensionVersion(1, 0, 0);
}
};
} // namespace rtc
} // namespace agora

View File

@@ -0,0 +1,26 @@
//
// AgoraRtcEngineKit.h
// AgoraRtcEngineKit
//
// Copyright (c) 2018 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "AgoraEnumerates.h"
/**
* The AgoraFaceInfoDelegate protocol enables face info callback event notifications to your application.
*/
@protocol AgoraFaceInfoDelegate <NSObject>
@optional
/**
* Occurs when the face info is received.
* @param outFaceInfo A pointer to the face info: NSString.
* @return
* - true: The face info is valid and sent.
* - false: The face info is invalid or sent.
*/
- (BOOL)onFaceInfo:(NSString* _Nonnull)outFaceInfo NS_SWIFT_NAME(onFaceInfo(_:));
@end

View File

@@ -0,0 +1,53 @@
//
// AgoraH265TranscoderDelegate.h
// AgoraH265TranscoderDelegate
//
// Copyright (c) 2022 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "AgoraEnumerates.h"
@protocol AgoraH265TranscoderDelegate <NSObject>
@optional
/**
* Use to notify the result of invoking enableTranscode interface.
* @param result Result of invoking enableTranscode interface. There are some processing advice below of result.
* - AgoraH265TranscodeResultRequestInvalid: Channel or uid param have a mistake, you need to check them for correctness.
* - AgoraH265TranscodeResultUnauthorized: Authentication failed, please check for correctness of token.
* - AgoraH265TranscodeResultTokenExpired: The token has expired, you need to generate a new token.
* - AgoraH265TranscodeResultForbidden: You need to contact agora staff to add the vid whitelist.
* - AgoraH265TranscodeResultNotFound: Indicates that the network may be faulty.
* - AgoraH265TranscodeResultTooOften: Request is too often, please request again later.
* - AgoraH265TranscodeResultServerInternalError: The service has an internal error. A request can be made again.
*/
- (void)onEnableTranscode:(AgoraH265TranscodeResult)result NS_SWIFT_NAME(onEnableTranscode(_:));
/**
* Use to notify the result of invoking queryChannel interface.
* @param result Result of invoking queryChannel interface. There are some processing advice below of result.
* - AgoraH265TranscodeResultUnauthorized: Authentication failed, please check for correctness of token.
* - AgoraH265TranscodeResultTokenExpired: The token has expired, you need to generate a new token.
* - AgoraH265TranscodeResultNotFound: Indicates that the network may be faulty or the channel param may be is empty.
* - AgoraH265TranscodeResultTooOften: Request is too often, please request again later.
* - AgoraH265TranscodeResultServerInternalError: The service has an internal error. A request can be made again.
*
* @param originChannel Origin channel id
* @param transcodeChannel Transcode channel id
*/
- (void)onQueryChannel:(AgoraH265TranscodeResult)result
originChannel:(NSString* _Nullable)originChannel
transcodeChannel:(NSString* _Nullable)transcodeChannel NS_SWIFT_NAME(onQueryChannel(_:originChannel:transcodeChannel:));
/** Use to notify the result of invoking triggerTranscode interface.
* @param result Result of invoking triggerTranscode interface. There are some processing advice below of result.
* - AgoraH265TranscodeResultUnauthorized: Authentication failed, please check for correctness of token.
* - AgoraH265TranscodeResultTokenExpired: The token has expired, you need to generate a new token.
* - AgoraH265TranscodeResultNotFound: Indicates that the network may be faulty or the channel param may be is empty.
* - AgoraH265TranscodeResultConflict: The request of trigger transcode is conflicted, please try again.
* - AgoraH265TranscodeResultTooOften: Request is too often, please request again later.
* - AgoraH265TranscodeResultServerInternalError: The service has an internal error. A request can be made again.
* - AgoraH265TranscodeResultServiceUnavailable: May be the number of transcode service is over the limit.
*/
- (void)onTriggerTranscode:(AgoraH265TranscodeResult)result NS_SWIFT_NAME(onTriggerTranscode(_:));
@end

View File

@@ -0,0 +1,71 @@
//
// AgoraH265TranscoderProtocol.h
// AgoraH265TranscoderProtocol
//
// Copyright (c) 2022 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
@protocol AgoraH265TranscoderDelegate;
@protocol AgoraH265TranscoderProtocol <NSObject>
/**
* Enable transcoding for a channel.
* @param token The token for authentication.
* @param channel The unique channel name for the AgoraRTC session in the string format.
* @param uid User ID.
* @return
* - 0: Success.
* - <0: Failure.
*/
- (NSInteger)enableTranscodeWithToken:(NSString* _Nonnull)token
channel:(NSString* _Nonnull)channel
uid:(NSUInteger)uid NS_SWIFT_NAME(enableTranscode(token:channel:uid:));
/**
* Query the transcoded channel of a channel.
* @param token The token for authentication.
* @param channel The unique channel name for the AgoraRTC session in the string format.
* @param uid User ID.
* @return
* - 0: Success.
* - <0: Failure.
*/
- (NSInteger)queryChannelWithToken:(NSString* _Nonnull)token
channel:(NSString* _Nonnull)channel
uid:(NSUInteger) uid NS_SWIFT_NAME(queryChannel(token:channel:uid:));
/**
* Trigger channel transcoding.
* @param token The token for authentication.
* @param channel The unique channel name for the AgoraRTC session in the string format.
* @param uid User ID.
* @return
* - 0: Success.
* - <0: Failure.
*/
- (NSInteger)triggerTranscodeWithToken:(NSString* _Nonnull)token
channel:(NSString* _Nonnull)channel
uid:(NSUInteger)uid NS_SWIFT_NAME(triggerTranscode(token:channel:uid:));
/**
* Register a AgoraH265TranscoderDelegate object.
* @param delegate AgoraH265TranscoderDelegate.
* @return
* - 0: Success.
* - <0: Failure.
*/
- (NSInteger)registerTranscoderDelegate:(id<AgoraH265TranscoderDelegate>_Nullable)delegate NS_SWIFT_NAME(registerTranscoderDelegate(_:));
/**
* Unregister a AgoraH265TranscoderDelegate object.
* @param delegate AgoraH265TranscoderDelegate.
* @return
* - 0: Success.
* - <0: Failure.
*/
- (NSInteger)unregisterTranscoderDelegate:(id<AgoraH265TranscoderDelegate>_Nullable)delegate NS_SWIFT_NAME(unregisterTranscoderDelegate(_:));
@end

View File

@@ -0,0 +1,52 @@
//
// AgoraMediaFilterEventDelegate.h
// Agora SDK
//
// Created by LLF on 2020-9-21.
// Copyright (c) 2020 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
/**
* The definition of extension context types.
*/
@interface AgoraExtensionContext : NSObject
/**
* Whether the uid is valid.
* - YES: The uid is valid.
* - NO: The uid is invalid.
*/
@property (assign, nonatomic) BOOL isValid;
/**
* The ID of the user.
* A uid of 0 indicates the local user, and a uid greater than 0 represents a remote user.
*/
@property (assign, nonatomic) NSUInteger uid;
/**
* The provider name of the current extension.
*/
@property (copy, nonatomic) NSString * _Nullable providerName;
/**
* The extension name of the current extension.
*/
@property (copy, nonatomic) NSString * _Nullable extensionName;
@end
@protocol AgoraMediaFilterEventDelegate <NSObject>
@optional
/* Meida filter(audio filter or video filter) event callback
*/
- (void)onEventWithContext:(AgoraExtensionContext * _Nonnull)context
key:(NSString * _Nullable)key
value:(NSString * _Nullable)value NS_SWIFT_NAME(onEventWithContext(_:key:value:));
- (void)onExtensionStartedWithContext:(AgoraExtensionContext * _Nonnull)context NS_SWIFT_NAME(onExtensionStartedWithContext(_:));
- (void)onExtensionStoppedWithContext:(AgoraExtensionContext * _Nonnull)context NS_SWIFT_NAME(onExtensionStoppedWithContext(_:));
- (void)onExtensionErrorWithContext:(AgoraExtensionContext * _Nonnull)context
error:(int)error
message:(NSString * _Nullable)message NS_SWIFT_NAME(onExtensionErrorWithContext(_:error:message:));
@end

View File

@@ -0,0 +1,53 @@
//
// AgoraRtcEngineKit.h
// AgoraRtcEngineKit
//
// Copyright (c) 2018 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "AgoraConstants.h"
#import "AgoraObjects.h"
#import "AgoraRtcMediaPlayerProtocol.h"
#import "AgoraH265TranscoderProtocol.h"
/** Agora provides ensured quality of experience (QoE) for worldwide Internet-based voice and video communications through a virtual global network that is especially optimized for real-time web and mobile-to-mobile applications.
The AgoraRtcEngineKit class is the entry point of the Agora SDK that provides simple APIs for applications to easily start voice and video communication.
*/
@class AgoraRtcEngineKit;
@class AgoraMediaRecorder;
/** The definition of the AgoraMediaMetadataDataSource protocol.
* @note Implement all the callbacks in this protocol in the critical thread. We recommend avoiding any time-consuming
* operation in the critical thread.
*/
@protocol AgoraMediaMetadataDataSource <NSObject>
@required
/** Occurs when the SDK requests the maximum size of the metadata.
*
* After calling the \ref AgoraRtcEngineKit.setMediaMetadataDataSource:withType: setMediaMetadataDataSource method,
* the SDK triggers this callback to query the maximum size of your metadata.
* You must specify the maximum size in the return value and then pass it to the SDK.
*
* @return The maximum size (bytes) of the buffer of the metadata. See \ref AgoraMediaMetadataDataSource.readyToSendMetadataAtTimestamp: readyToSendMetadataAtTimestamp. The value must not exceed 1024 bytes.
* You must specify the maximum size in this return value.
*/
- (NSInteger)metadataMaxSize NS_SWIFT_NAME(metadataMaxSize());
/** Occurs when the SDK is ready to send metadata.
You need to specify the metadata in the return value of this method.
@note Ensure that the size of the metadata that you specify in this callback does not exceed the value set in the \ref AgoraMediaMetadataDataSource.metadataMaxSize metadataMaxSize callback.
@param timestamp The timestamp (ms) of the current metadata.
@return The metadata that you want to send in the format of NSData, including the following parameters:
- `uid`: ID of the user who sends the metadata.
- `size`: The size of the sent metadata.
- `buffer`: The sent metadata.
- `timeStampMs`: The NTP timestamp (ms) when the metadata is sent.
*/
- (NSData * _Nullable)readyToSendMetadataAtTimestamp:(NSTimeInterval)timestamp sourceType:(AgoraVideoSourceType)sourceType NS_SWIFT_NAME(readyToSendMetadata(atTimestamp:sourceType:));
@end

View File

@@ -0,0 +1,31 @@
//
// AgoraRtcEngineKit.h
// AgoraRtcEngineKit
//
// Copyright (c) 2018 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "AgoraObjects.h"
/** The definition of AgoraMediaMetadataDelegate.
@note Implement the callback in this protocol in the critical thread. We recommend avoiding any time-consuming operation in the critical thread.
*/
@protocol AgoraMediaMetadataDelegate <NSObject>
@required
/** Occurs when the local user receives the metadata.
*
* @param metadata The received metadata. See \ref AgoraMetadata.
*/
- (void)didMetadataReceived:(AgoraMetadata * _Nonnull)metadata NS_SWIFT_NAME(didMetadataReceived(_:));
@optional
/* Unavailable Delegate Methods */
#if TARGET_OS_IPHONE
- (void)receiveMetadata:(NSData * _Nonnull)data fromUser:(NSInteger)uid atTimestamp:(NSTimeInterval)timestamp NS_SWIFT_NAME(receiveMetadata(_:fromUser:atTimestamp:)) __attribute__((availability(ios,deprecated=7_0,message="Use didMetadataReceived: instead.")));
#endif
#if (!(TARGET_OS_IPHONE) && (TARGET_OS_MAC))
- (void)receiveMetadata:(NSData * _Nonnull)data fromUser:(NSInteger)uid atTimestamp:(NSTimeInterval)timestamp NS_SWIFT_NAME(receiveMetadata(_:fromUser:atTimestamp:)) __attribute__((availability(macos,deprecated=10_9,message="Use didMetadataReceived: instead.")));
#endif
@end

View File

@@ -0,0 +1,520 @@
//
// Agora Engine SDK
//
// Created by Sting Feng in 2020-05.
// Copyright (c) 2017 Agora.io. All rights reserved.
#pragma once // NOLINT(build/header_guard)
#include <cstring>
#include <stdint.h>
#include "AgoraOptional.h"
/**
* set analyze duration for real time stream
* @example "setPlayerOption(KEY_PLAYER_REAL_TIME_STREAM_ANALYZE_DURATION,1000000)"
*/
#define KEY_PLAYER_REAL_TIME_STREAM_ANALYZE_DURATION "analyze_duration"
/**
* make the player to enable audio or not
* @example "setPlayerOption(KEY_PLAYER_ENABLE_AUDIO,0)"
*/
#define KEY_PLAYER_ENABLE_AUDIO "enable_audio"
/**
* make the player to enable video or not
* @example "setPlayerOption(KEY_PLAYER_ENABLE_VIDEO,0)"
*/
#define KEY_PLAYER_ENABLE_VIDEO "enable_video"
/**
* set the player enable to search metadata
* @example "setPlayerOption(KEY_PLAYER_DISABLE_SEARCH_METADATA,0)"
*/
#define KEY_PLAYER_ENABLE_SEARCH_METADATA "enable_search_metadata"
/**
* set the player sei filter type
* @example "setPlayerOption(KEY_PLAYER_SEI_FILTER_TYPE,"5")"
*/
#define KEY_PLAYER_SEI_FILTER_TYPE "set_sei_filter_type"
namespace agora {
namespace media {
namespace base {
static const uint8_t kMaxCharBufferLength = 50;
/**
* @brief The playback state.
*
*/
enum MEDIA_PLAYER_STATE {
/** Default state.
*/
PLAYER_STATE_IDLE = 0,
/** Opening the media file.
*/
PLAYER_STATE_OPENING,
/** The media file is opened successfully.
*/
PLAYER_STATE_OPEN_COMPLETED,
/** Playing the media file.
*/
PLAYER_STATE_PLAYING,
/** The playback is paused.
*/
PLAYER_STATE_PAUSED,
/** The playback is completed.
*/
PLAYER_STATE_PLAYBACK_COMPLETED,
/** All loops are completed.
*/
PLAYER_STATE_PLAYBACK_ALL_LOOPS_COMPLETED,
/** The playback is stopped.
*/
PLAYER_STATE_STOPPED,
/** Player pausing (internal)
*/
PLAYER_STATE_PAUSING_INTERNAL = 50,
/** Player stopping (internal)
*/
PLAYER_STATE_STOPPING_INTERNAL,
/** Player seeking state (internal)
*/
PLAYER_STATE_SEEKING_INTERNAL,
/** Player getting state (internal)
*/
PLAYER_STATE_GETTING_INTERNAL,
/** None state for state machine (internal)
*/
PLAYER_STATE_NONE_INTERNAL,
/** Do nothing state for state machine (internal)
*/
PLAYER_STATE_DO_NOTHING_INTERNAL,
/** Player set track state (internal)
*/
PLAYER_STATE_SET_TRACK_INTERNAL,
/** The playback fails.
*/
PLAYER_STATE_FAILED = 100,
};
/**
* @brief Player error code
*
*/
enum MEDIA_PLAYER_REASON {
/** No error.
*/
PLAYER_REASON_NONE = 0,
/** The parameter is invalid.
*/
PLAYER_REASON_INVALID_ARGUMENTS = -1,
/** Internel error.
*/
PLAYER_REASON_INTERNAL = -2,
/** No resource.
*/
PLAYER_REASON_NO_RESOURCE = -3,
/** Invalid media source.
*/
PLAYER_REASON_INVALID_MEDIA_SOURCE = -4,
/** The type of the media stream is unknown.
*/
PLAYER_REASON_UNKNOWN_STREAM_TYPE = -5,
/** The object is not initialized.
*/
PLAYER_REASON_OBJ_NOT_INITIALIZED = -6,
/** The codec is not supported.
*/
PLAYER_REASON_CODEC_NOT_SUPPORTED = -7,
/** Invalid renderer.
*/
PLAYER_REASON_VIDEO_RENDER_FAILED = -8,
/** An error occurs in the internal state of the player.
*/
PLAYER_REASON_INVALID_STATE = -9,
/** The URL of the media file cannot be found.
*/
PLAYER_REASON_URL_NOT_FOUND = -10,
/** Invalid connection between the player and the Agora server.
*/
PLAYER_REASON_INVALID_CONNECTION_STATE = -11,
/** The playback buffer is insufficient.
*/
PLAYER_REASON_SRC_BUFFER_UNDERFLOW = -12,
/** The audio mixing file playback is interrupted.
*/
PLAYER_REASON_INTERRUPTED = -13,
/** The SDK does not support this function.
*/
PLAYER_REASON_NOT_SUPPORTED = -14,
/** The token has expired.
*/
PLAYER_REASON_TOKEN_EXPIRED = -15,
/** The ip has expired.
*/
PLAYER_REASON_IP_EXPIRED = -16,
/** An unknown error occurs.
*/
PLAYER_REASON_UNKNOWN = -17,
};
/**
* @brief The type of the media stream.
*
*/
enum MEDIA_STREAM_TYPE {
/** The type is unknown.
*/
STREAM_TYPE_UNKNOWN = 0,
/** The video stream.
*/
STREAM_TYPE_VIDEO = 1,
/** The audio stream.
*/
STREAM_TYPE_AUDIO = 2,
/** The subtitle stream.
*/
STREAM_TYPE_SUBTITLE = 3,
};
/**
* @brief The playback event.
*
*/
enum MEDIA_PLAYER_EVENT {
/** The player begins to seek to the new playback position.
*/
PLAYER_EVENT_SEEK_BEGIN = 0,
/** The seek operation completes.
*/
PLAYER_EVENT_SEEK_COMPLETE = 1,
/** An error occurs during the seek operation.
*/
PLAYER_EVENT_SEEK_ERROR = 2,
/** The player changes the audio track for playback.
*/
PLAYER_EVENT_AUDIO_TRACK_CHANGED = 5,
/** player buffer low
*/
PLAYER_EVENT_BUFFER_LOW = 6,
/** player buffer recover
*/
PLAYER_EVENT_BUFFER_RECOVER = 7,
/** The video or audio is interrupted
*/
PLAYER_EVENT_FREEZE_START = 8,
/** Interrupt at the end of the video or audio
*/
PLAYER_EVENT_FREEZE_STOP = 9,
/** switch source begin
*/
PLAYER_EVENT_SWITCH_BEGIN = 10,
/** switch source complete
*/
PLAYER_EVENT_SWITCH_COMPLETE = 11,
/** switch source error
*/
PLAYER_EVENT_SWITCH_ERROR = 12,
/** An application can render the video to less than a second
*/
PLAYER_EVENT_FIRST_DISPLAYED = 13,
/** cache resources exceed the maximum file count
*/
PLAYER_EVENT_REACH_CACHE_FILE_MAX_COUNT = 14,
/** cache resources exceed the maximum file size
*/
PLAYER_EVENT_REACH_CACHE_FILE_MAX_SIZE = 15,
/** Triggered when a retry is required to open the media
*/
PLAYER_EVENT_TRY_OPEN_START = 16,
/** Triggered when the retry to open the media is successful
*/
PLAYER_EVENT_TRY_OPEN_SUCCEED = 17,
/** Triggered when retrying to open media fails
*/
PLAYER_EVENT_TRY_OPEN_FAILED = 18,
/** Triggered when an http redirect occurs
* @technical preview
*/
PLAYER_EVENT_HTTP_REDIRECT = 19,
};
/**
* @brief The play preload another source event.
*
*/
enum PLAYER_PRELOAD_EVENT {
/** preload source begin
*/
PLAYER_PRELOAD_EVENT_BEGIN = 0,
/** preload source complete
*/
PLAYER_PRELOAD_EVENT_COMPLETE = 1,
/** preload source error
*/
PLAYER_PRELOAD_EVENT_ERROR = 2,
};
/**
* @brief The information of the media stream object.
*
*/
struct PlayerStreamInfo {
/** The index of the media stream. */
int streamIndex;
/** The type of the media stream. See {@link MEDIA_STREAM_TYPE}. */
MEDIA_STREAM_TYPE streamType;
/** The codec of the media stream. */
char codecName[kMaxCharBufferLength];
/** The language of the media stream. */
char language[kMaxCharBufferLength];
/** The frame rate (fps) if the stream is video. */
int videoFrameRate;
/** The video bitrate (bps) if the stream is video. */
int videoBitRate;
/** The video width (pixel) if the stream is video. */
int videoWidth;
/** The video height (pixel) if the stream is video. */
int videoHeight;
/** The rotation angle if the steam is video. */
int videoRotation;
/** The sample rate if the stream is audio. */
int audioSampleRate;
/** The number of audio channels if the stream is audio. */
int audioChannels;
/** The number of bits per sample if the stream is audio. */
int audioBitsPerSample;
/** The total duration (millisecond) of the media stream. */
int64_t duration;
PlayerStreamInfo() : streamIndex(0),
streamType(STREAM_TYPE_UNKNOWN),
videoFrameRate(0),
videoBitRate(0),
videoWidth(0),
videoHeight(0),
videoRotation(0),
audioSampleRate(0),
audioChannels(0),
audioBitsPerSample(0),
duration(0) {
memset(codecName, 0, sizeof(codecName));
memset(language, 0, sizeof(language));
}
};
/**
* @brief The information of the media stream object.
*
*/
struct SrcInfo {
/** The bitrate of the media stream. The unit of the number is kbps.
*
*/
int bitrateInKbps;
/** The name of the media stream.
*
*/
const char* name;
};
/**
* @brief The type of the media metadata.
*
*/
enum MEDIA_PLAYER_METADATA_TYPE {
/** The type is unknown.
*/
PLAYER_METADATA_TYPE_UNKNOWN = 0,
/** The type is SEI.
*/
PLAYER_METADATA_TYPE_SEI = 1,
};
struct CacheStatistics {
/** total data size of uri
*/
int64_t fileSize;
/** data of uri has cached
*/
int64_t cacheSize;
/** data of uri has downloaded
*/
int64_t downloadSize;
};
/**
* @brief The real time statistics of the media stream being played.
*
*/
struct PlayerPlaybackStats {
/** Video fps.
*/
int videoFps;
/** Video bitrate (Kbps).
*/
int videoBitrateInKbps;
/** Audio bitrate (Kbps).
*/
int audioBitrateInKbps;
/** Total bitrate (Kbps).
*/
int totalBitrateInKbps;
};
/**
* @brief The updated information of media player.
*
*/
struct PlayerUpdatedInfo {
/** @technical preview
*/
const char* internalPlayerUuid;
/** The device ID of the playback device.
*/
const char* deviceId;
/** Video height.
*/
int videoHeight;
/** Video width.
*/
int videoWidth;
/** Audio sample rate.
*/
int audioSampleRate;
/** The audio channel number.
*/
int audioChannels;
/** The bit number of each audio sample.
*/
int audioBitsPerSample;
PlayerUpdatedInfo()
: internalPlayerUuid(NULL),
deviceId(NULL),
videoHeight(0),
videoWidth(0),
audioSampleRate(0),
audioChannels(0),
audioBitsPerSample(0) {}
};
/**
* The custom data source provides a data stream input callback, and the player will continue to call back this interface, requesting the user to fill in the data that needs to be played.
*/
class IMediaPlayerCustomDataProvider {
public:
/**
* @brief The player requests to read the data callback, you need to fill the specified length of data into the buffer
* @param buffer the buffer pointer that you need to fill data.
* @param bufferSize the bufferSize need to fill of the buffer pointer.
* @return you need return offset value if succeed. return 0 if failed.
*/
virtual int onReadData(unsigned char *buffer, int bufferSize) = 0;
/**
* @brief The Player seek event callback, you need to operate the corresponding stream seek operation, You can refer to the definition of lseek() at https://man7.org/linux/man-pages/man2/lseek.2.html
* @param offset the value of seek offset.
* @param whence the postion of start seeking, the directive whence as follows:
* 0 - SEEK_SET : The file offset is set to offset bytes.
* 1 - SEEK_CUR : The file offset is set to its current location plus offset bytes.
* 2 - SEEK_END : The file offset is set to the size of the file plus offset bytes.
* 65536 - AVSEEK_SIZE : Optional. Passing this as the "whence" parameter to a seek function causes it to return the filesize without seeking anywhere.
* @return
* whence == 65536, return filesize if you need.
* whence >= 0 && whence < 3 , return offset value if succeed. return -1 if failed.
*/
virtual int64_t onSeek(int64_t offset, int whence) = 0;
virtual ~IMediaPlayerCustomDataProvider() {}
};
struct MediaSource {
/**
* The URL of the media file that you want to play.
*/
const char* url;
/**
* The URI of the media file
*
* When caching is enabled, if the url cannot distinguish the cache file name,
* the uri must be able to ensure that the cache file name corresponding to the url is unique.
*/
const char* uri;
/**
* Set the starting position for playback, in ms.
*/
int64_t startPos;
/**
* Determines whether to autoplay after opening a media resource.
* - true: (Default) Autoplay after opening a media resource.
* - false: Do not autoplay after opening a media resource.
*/
bool autoPlay;
/**
* Determines whether to enable cache streaming to local files. If enable cached, the media player will
* use the url or uri as the cache index.
*
* @note
* The local cache function only supports on-demand video/audio streams and does not support live streams.
* Caching video and audio files based on the HLS protocol (m3u8) to your local device is not supported.
*
* - true: Enable cache.
* - false: (Default) Disable cache.
*/
bool enableCache;
/**
* Determines whether to enable multi-track audio stream decoding.
* Then you can select multi audio track of the media file for playback or publish to channel
*
* @note
* If you use the selectMultiAudioTrack API, you must set enableMultiAudioTrack to true.
*
* - true: Enable MultiAudioTrack;.
* - false: (Default) Disable MultiAudioTrack;.
*/
bool enableMultiAudioTrack;
/**
* Determines whether the opened media resource is a stream through the Agora Broadcast Streaming Network(CDN).
* - true: It is a stream through the Agora Broadcast Streaming Network.
* - false: (Default) It is not a stream through the Agora Broadcast Streaming Network.
*/
Optional<bool> isAgoraSource;
/**
* Determines whether the opened media resource is a live stream. If is a live stream, it can speed up the opening of media resources.
* - true: It is a live stream.
* - false: (Default) It is not is a live stream.
*/
Optional<bool> isLiveSource;
/**
* External custom data source object
*/
IMediaPlayerCustomDataProvider* provider;
MediaSource() : url(NULL), uri(NULL), startPos(0), autoPlay(true), enableCache(false),
enableMultiAudioTrack(false), provider(NULL){
}
};
} // namespace base
} // namespace media
} // namespace agora

View File

@@ -0,0 +1,104 @@
//
// AgoraRtcEngineKit.h
// AgoraRtcEngineKit
//
// Copyright (c) 2018 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
@protocol AgoraMediaRecorderDelegate;
@class AgoraMediaRecorderConfiguration;
__attribute__((visibility("default"))) @interface AgoraMediaRecorder : NSObject
/**
* Registers the AgoraMediaRecorderDelegate delegate.
*
* @since v4.0.0
*
* @note Call this method before the startRecording method.
*
* @param delegate The callbacks for recording audio and video streams. See AgoraMediaRecorderDelegate
*
* @return
* - 0(ERR_OK): Success.
* - < 0: Failure:
*/
- (int)setMediaRecorderDelegate:(id<AgoraMediaRecorderDelegate> _Nullable)delegate;
/** Enables/Disables dispatching delegate methods to the main queue.
* If disabled, the app should dispatch UI operations to the main queue.
* @param enabled Sets whether or not to dispatch delegate methods to the main queue:
* YES: Dispatch delegate methods to the main queue.
* NO: Do not dispatch delegate methods to the main queue
* @return * 0: Success.
* < 0: Failure.
*/
- (int)enableMainQueueDispatch:(BOOL)enabled NS_SWIFT_NAME(enableMainQueueDispatch(_:));
/**
* Starts recording the local audio and video.
*
* @since v4.0.0
*
* After successfully calling \ref AgoraRtcEngineKit.createMediaRecorder: createMediaRecorder to get the media recorder object
* , you can call this method to enable the recording of the local audio and video.
*
* This method can record the following content:
* - The audio captured by the local microphone and encoded in AAC format.
* - The video captured by the local camera and encoded by the SDK.
*
* This method can record the following content:
* - The audio received from remote users and encoded in AAC format.
* - The video received from remote users.
*
*
* The SDK can generate a recording file only when it detects the recordable audio and video streams; when there are
* no audio and video streams to be recorded or the audio and video streams are interrupted for more than five
* seconds, the SDK stops recording and triggers the
* \ref AgoraMediaRecorderDelegate.stateDidChanged "stateDidChanged" (AgoraMediaRecorderState, AgoraMediaRecorderReasonCode)
* callback.
*
* @note Call this method after joining the channel.
*
* @param config The recording configurations. See AgoraMediaRecorderConfiguration object.
*
* @return
* - 0(ERR_OK): Success.
* - < 0: Failure:
* - `-1(ERR_FAILED)`: IRtcEngine does not support the request due to one of the following reasons:
* - During remote recording, There is no subscription to the target channel or user。
* - `-2(ERR_INVALID_ARGUMENT)`: The parameter is invalid. Ensure the following:
* - The specified path of the recording file exists and is writable.
* - The specified format of the recording file is supported.
* - The maximum recording duration is correctly set.
* - During remote recording, ensure the user whose media streams you want record did join the channel.
* - `-4(ERR_NOT_SUPPORTED)`: IRtcEngine does not support the request due to one of the following reasons:
* - The recording is ongoing.
* - The recording stops because an error occurs.
* - No \ref AgoraMediaRecorderDelegate object is registered.
*/
- (int)startRecording:(AgoraMediaRecorderConfiguration* _Nonnull)config NS_SWIFT_NAME(startRecording(_:));
/**
* Stops recording the audio and video.
*
* @since v4.0.0
*
* @note After calling \ref AgoraMediaRecorder.startRecording: startRecording, if you want to stop the recording,
* you must call `stopRecording`; otherwise, the generated recording files might not be playable.
*
*
* @return
* - 0(ERR_OK): Success.
* - < 0: Failure:
*/
/**
Stop recording.
@return 0: Success.
* < 0: Failure.
*/
- (int)stopRecording NS_SWIFT_NAME(stopRecording());
@end

View File

@@ -0,0 +1,49 @@
//
// Copyright (c) 2018 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
@class AgoraMediaRecorder;
@class AgoraMediaRecorderInfo;
typedef NS_ENUM(NSInteger, AgoraMediaRecorderState);
typedef NS_ENUM(NSInteger, AgoraMediaRecorderReasonCode);
@protocol AgoraMediaRecorderDelegate <NSObject>
#pragma mark Media Recorder Delegate Methods
/**-----------------------------------------------------------------------------
* @name Media Recorder Delegate Methods
* -----------------------------------------------------------------------------
*/
/** Occurs when media recorder state is changed.
*
* @since v4.0.0
*
* When the local audio and video recording state changes, the SDK triggers this callback to report the current
* recording state and the reason for the change.
*
* @param recorder AgoraMediaRecorder object.
* @param state Recorder state. See AgoraMediaRecorderState.
* @param reason Error code. See AgoraMediaRecorderReasonCode.
* @param channelId The channel name.
* @param uid ID of the user.
*/
- (void)mediaRecorder:(AgoraMediaRecorder* _Nonnull)recorder stateDidChanged:(NSString * _Nonnull)channelId uid:(NSUInteger)uid state:(AgoraMediaRecorderState)state reason:(AgoraMediaRecorderReasonCode)reason;
/** Occurs when media recorder information is updated.
*
* @since v4.0.0
*
* After you successfully register this callback and enable the local audio and video recording, the SDK periodically triggers
* the `onRecorderInfoUpdated` callback based on the set value of `recorderInfoUpdateInterval`. This callback reports the
* filename, duration, and size of the current recording file.
*
* @param recorder AgoraMediaRecorder object.
* @param info Information about the recording file.. See AgoraMediaRecorderInfo.
* @param channelId The channel name.
* @param uid ID of the user.
*/
- (void)mediaRecorder:(AgoraMediaRecorder* _Nonnull)recorder informationDidUpdated:(NSString * _Nonnull)channelId uid:(NSUInteger)uid info:(AgoraMediaRecorderInfo* _Nonnull)info;
@end

View File

@@ -0,0 +1,551 @@
//
// AgoraMusicContentCenter.h
// AgoraMusicContentCenter
//
// Created by dingyusong on 2022/6/1.
// Copyright © 2022 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
@protocol AgoraRtcMediaPlayerProtocol;
@protocol AgoraRtcMediaPlayerDelegate;
/**
* Modes for playing songs.
*/
typedef NS_ENUM(NSUInteger, AgoraMusicPlayMode) {
/**
* 0: The music player is in the origin mode, which means playing the original song.
*/
AgoraMusicPlayModeOriginal = 0,
/**
* The music player is in the accompany mode, which means playing the accompaniment only.
*/
AgoraMusicPlayModeAccompany = 1,
/**
* 2: The music player is in the lead sing mode, which means playing the lead vocals.
*/
AgoraMusicPlayModeLeadsing = 2,
};
/**
* The status of preload request
*/
typedef NS_ENUM(NSUInteger, AgoraMusicContentCenterPreloadState) {
/**
* 0: No error occurs and preload succeeds.
*/
AgoraMusicContentCenterPreloadStateOK = 0,
/**
* 1: A general error occurs.
*/
AgoraMusicContentCenterPreloadStateError = 1,
/**
* 2: The media file is preloading.
*/
AgoraMusicContentCenterPreloadStatePreloading = 2,
/**
* 3: The media file is removed.
*/
AgoraMusicContentCenterPreloadStateRemoveCache = 3,
};
/**
* the status of search or get top list request
*/
typedef NS_ENUM(NSUInteger, AgoraMusicContentCenterStateReason) {
/**
* 0: No error occurs and request succeeds.
*/
AgoraMusicContentCenterStateReasonOK = 0,
/**
* 1: The gateway error. There are several possible reasons:
* - Token is expired. Check if your token is expired.
* - Token is invalid. Check the type of token you passed in.
* - Network error. Check your network.
*/
AgoraMusicContentCenterStateReasonError = 1,
/**
* 2: The gateway error. There are several possible reasons:
* - Token is expired. Check if your token is expired.
* - Token is invalid. Check the type of token you passed in.
* - Network error. Check your network.
*/
AgoraMusicContentCenterStateReasonErrorGateway = 2,
/**
* 3: Permission and resource error. There are several possible reasons:
* - Your appid may not have the mcc permission. Please contact technical support
* - The resource may not exist. Please contact technical support
*/
AgoraMusicContentCenterStateReasonErrorPermissionAndResource = 3,
/**
* 4: Internal data parse error. Please contact technical support
*/
AgoraMusicContentCenterStateReasonErrorInternalDataParse = 4,
/**
* 5: Music loading error. Please contact technical support
*/
AgoraMusicContentCenterStateReasonErrorMusicLoading = 5,
/**
* 6: Music decryption error. Please contact technical support
*/
AgoraMusicContentCenterStateReasonErrorMusicDecryption = 6,
/**
* 7: Http internal error. Please retry later.
*/
AgoraMusicContentCenterStateReasonErrorHttpInternalError = 7,
};
typedef NS_ENUM(NSUInteger, AgoraMusicCacheStatusType) {
/**
* 0: The media file is already cached.
*/
AgoraMusicCacheStatusTypeCached = 0,
/**
* 1: The media file is being cached.
*/
AgoraMusicCacheStatusTypeCaching = 1,
};
NS_ASSUME_NONNULL_BEGIN
__attribute__((visibility("default"))) @interface AgoraMusicCacheInfo : NSObject
/**
* The songCode of the music
*/
@property(nonatomic, assign) NSInteger songCode;
/**
* The cache status of the music
*/
@property(nonatomic, assign) AgoraMusicCacheStatusType statusType;
@end
__attribute__((visibility("default"))) @interface AgoraMusicChartInfo : NSObject
/**
* Name of the music chart
*/
@property (nonatomic, copy) NSString *chartName;
/**
* Id of the music chart, which is used to get music list
*/
@property (nonatomic, assign) NSInteger identify;
@end
__attribute__((visibility("default"))) @interface AgoraMvProperty : NSObject
/**
* The resolution of the mv
*/
@property (nonatomic, copy) NSString *resolution;
/**
* The bandwidth of the mv
*/
@property (nonatomic, copy) NSString *bandwidth;
@end
__attribute__((visibility("default"))) @interface AgoraClimaxSegment : NSObject
/**
* The start time of climax segment
*/
@property(nonatomic, assign) NSInteger startTimeMs;
/**
* The end time of climax segment
*/
@property(nonatomic, assign) NSInteger endTimeMs;
@end
/**
* The music info
*/
__attribute__((visibility("default"))) @interface AgoraMusic : NSObject
/**
* The songCode of music
*/
@property(nonatomic, assign) NSInteger songCode;
/**
* The type of music
* 1, mp3 with instrumental accompaniment and original
* 2, mp3 only with instrumental accompaniment
* 3, mp3 only with original
* 4, mp4 with instrumental accompaniment and original
* 5, mv only
* 6, new type mp4 with instrumental accompaniment and original
* detail at document of music media center
*/
@property(nonatomic, assign) NSInteger type;
/**
* The pitch type of music.
* 1, xml lyric has pitch
* 2, lyric has no pitch
*/
@property(nonatomic, assign) NSInteger pitchType;
/**
* The name of music
*/
@property(nonatomic, copy) NSString* name;
/**
* The singer of music
*/
@property(nonatomic, copy) NSString* singer;
/**
* The poster url of music
*/
@property(nonatomic, copy) NSString* poster;
/**
* The release time of music
*/
@property(nonatomic, copy) NSString* releaseTime;
/**
* The duration (in seconds) of music
*/
@property(nonatomic, assign) NSInteger durationS;
/**
* The lyric list of music
* 0, xml
* 1, lrc
*/
@property(nonatomic, strong) NSArray<NSNumber *>* lyricList;
/**
* The mv property list of music
*/
@property(nonatomic, strong) NSArray<AgoraMvProperty *>* mvPropertyList;
/**
* The climax segment list of music
*/
@property(nonatomic, strong) NSArray<AgoraClimaxSegment *>* climaxSegmentList;
@end
/**
* The music collection info
*/
__attribute__((visibility("default"))) @interface AgoraMusicCollection : NSObject
/**
* This page contains how many AgoraMusic object
*/
@property(nonatomic, assign) NSInteger count;
/**
* Total number of this search result or total number of the type music sources
*/
@property(nonatomic, assign) NSInteger total;
/**
* This current page number
*/
@property(nonatomic, assign) NSInteger page;
/**
* This request page size
*/
@property(nonatomic, assign) NSInteger pageSize;
/**
* This music list of the request result
*/
@property(nonatomic, strong) NSArray<AgoraMusic *>* musicList;
@end
/**
* The request event delegate callback
*/
@protocol AgoraMusicContentCenterEventDelegate <NSObject>
/**
* The music chart result callback; occurs when getMusicCharts method is called.
*
* @param requestId The request id is same as that returned by getMusicCharts.
* @param result The result of music chart collection
* @param reason The status of the request. See MusicContentCenterStateReason
*/
- (void)onMusicChartsResult:(NSString *)requestId result:(NSArray<AgoraMusicChartInfo*> *)result reason:(AgoraMusicContentCenterStateReason)reason;
/**
* Music collection, occurs when getMusicCollectionByMusicChartId or searchMusic method is called.
*
* @param requestId The request id is the same with that returned by getMusicCollectionByMusicChartId or searchMusic
* @param result The result of music collection
* @param reason The status of the request. See MusicContentCenterStateReason
*/
- (void)onMusicCollectionResult:(NSString *)requestId result:(AgoraMusicCollection *)result reason:(AgoraMusicContentCenterStateReason)reason;
/**
* Lyric url callback of getLyric, occurs when getLyric is called
*
* @param requestId The request id is same as that returned by getLyric
* @param songCode Song code
* @param lyricUrl The lyric url of this music
* @param reason The status of the request. See MusicContentCenterStateReason
*/
- (void)onLyricResult:(NSString*)requestId songCode:(NSInteger)songCode lyricUrl:(NSString* _Nullable)lyricUrl reason:(AgoraMusicContentCenterStateReason)reason;
/**
* Simple info callback of getSongSimpleInfo, occurs when getSongSimpleInfo is called
*
* @param requestId The request id is same as that returned by getSongSimpleInfo.
* @param songCode Song code
* @param simpleInfo The metadata of the music.
* @param reason The status of the request. See MusicContentCenterStateReason
*/
- (void)onSongSimpleInfoResult:(NSString*)requestId songCode:(NSInteger)songCode simpleInfo:(NSString* _Nullable)simpleInfo reason:(AgoraMusicContentCenterStateReason)reason;
/**
* Preload process callback, occurs when preload is called
*
* @param requestId The request id is same as that returned by preload.
* @param songCode Song code
* @param percent Preload progress (0 ~ 100)
* @param lyricUrl The lyric url of this music
* @param state Preload state; see PreloadState.
* @param reason The status of the request. See MusicContentCenterStateReason
*/
- (void)onPreLoadEvent:(NSString*)requestId songCode:(NSInteger)songCode percent:(NSInteger)percent lyricUrl:(NSString * _Nullable)lyricUrl state:(AgoraMusicContentCenterPreloadState)state reason:(AgoraMusicContentCenterStateReason)reason;
@end
@class AgoraRtcEngineKit;
__attribute__((visibility("default"))) @interface AgoraMusicContentCenterConfig : NSObject
@property(assign, nonatomic) AgoraRtcEngineKit* _Nullable rtcEngine;
/**
* The app ID of the project that has enabled the music content center
*/
@property (nonatomic, copy) NSString *appId;
/**
* music content center need token to connect with server
*/
@property (nonatomic, copy) NSString *token;
/**
* The user ID when using music content center. It can be different from that of the rtc product.
*/
@property (nonatomic, assign) NSInteger mccUid;
/**
* The max number which the music content center caches cannot exceed 50.
*/
@property (nonatomic, assign) NSUInteger maxCacheSize;
/**
* @technical preview
*/
@property(nonatomic, copy) NSString* mccDomain;
/**
* Event handler to get callback result.
*/
@property(nonatomic, weak) id<AgoraMusicContentCenterEventDelegate> eventDelegate;
@end
@protocol AgoraMusicPlayerProtocol <AgoraRtcMediaPlayerProtocol>
/**
* Open a media file with specified parameters.
*
* @param songCode The identifier of the media file that you want to play.
* @param startPos The playback position (ms) of the music file.
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (NSInteger)openMediaWithSongCode:(NSInteger)songCode startPos:(NSInteger)startPos NS_SWIFT_NAME(openMedia(songCode:startPos:));
/**
* Set the mode for playing songs.
* You can call this method to switch from original to accompaniment or lead vocals.
* If you do not call this method to set the mode, the SDK plays the accompaniment by default.
*
* @param model The playing mode.
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (NSInteger)setPlayMode:(AgoraMusicPlayMode)mode NS_SWIFT_NAME(setPlayMode(mode:));
@end
__attribute__((visibility("default"))) @interface AgoraMusicContentCenter : NSObject
/**
* Create an AgoraMusicContentCenter instance.
*
* @param config Configurations for the AgoraMusicContentCenter instance. For details, see AgoraMusicContentCenterConfig.
* @return An shared instance of AgoraMusicContentCenter
*/
+ (instancetype _Nullable)sharedContentCenterWithConfig:(AgoraMusicContentCenterConfig *)config NS_SWIFT_NAME(sharedContentCenter(config:));
/**
* Renew token of music content center
* @param token The new token.
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (NSInteger)renewToken:(NSString * _Nonnull)token;
/**
* Register an event delegate, only the last delegate is working.
*
* @param eventDelegate the object who need AgoraRtcMediaPlayerDelegate method to get the player information ,
* if you want remove the delegate, just pass nil
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (NSInteger)registerEventDelegate:(id<AgoraMusicContentCenterEventDelegate> _Nullable)eventDelegate;
/**
* Creates a music player source object and return its pointer.
*
* @param delegate The object who need AgoraRtcMediaPlayerDelegate method to get the player information
* @return
* - The pointer to an object who realize the AgoraMusicPlayerProtocol, if the method call succeeds.
* - The empty pointer NULL, if the method call fails.
*/
- (id<AgoraMusicPlayerProtocol> _Nullable)createMusicPlayerWithDelegate:(id<AgoraRtcMediaPlayerDelegate> _Nullable)delegate NS_SWIFT_NAME(createMusicPlayer(delegate:));
/**
* Destroy a music player source object and return result.
*
* @param musicPlayer The music player.
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (NSInteger)destroyMusicPlayer:(id<AgoraMusicPlayerProtocol>)musicPlayer;
/**
* Get music chart collection of music.If the method call success, get result from the AgoraMusicContentCenterEventDelegate - (void)onMusicChartsResult:(NSString *)requestId status:(AgoraMusicContentCenterStatusCode)status result:(NSArray<AgoraMusicChartInfo*> *)result; match the callback "requestId" parameter to get the request result.
*
* @return The request identification
*/
- (NSString *)getMusicCharts;
/**
* Get hot music list by hotType and page info.If the method call success, get result from the AgoraMusicContentCenterEventDelegate - (void)onMusicCollectionResult:(NSString *)requestId status:(AgoraMusicContentCenterStateReason)status result:(AgoraMusicCollection *)result; match the callback "requestId" parameter to get the request result.
*
* @param musicChartId The music chart id obtained from getMusicCharts.
* @param page The page of the music chart, starting from 1
* @param pageSize The page size, max is 50.
* @param jsonOption The ext param, default is null.
* @return The request identification
*/
- (NSString *)getMusicCollectionWithMusicChartId:(NSInteger)musicChartId page:(NSInteger)page pageSize:(NSInteger)pageSize jsonOption:(NSString * _Nullable)jsonOption NS_SWIFT_NAME(getMusicCollection(musicChartId:page:pageSize:jsonOption:));
/**
* Search music by keyword and page info. get result from the AgoraMusicContentCenterEventDelegate - (void)onMusicCollectionResult:(NSString *)requestId status:(AgoraMusicContentCenterStateReason)status result:(AgoraMusicCollection *)result; match the callback "requestId" parameter to get the request result.
*
* @param keyWord The key word to search.
* @param page The page of the music search result, starting from 1
* @param pageSize The page size, max is 50.
* @param jsonOption The ext param, default is null.
* @return The request identification
*/
- (NSString *)searchMusicWithKeyWord:(NSString *)keyWord page:(NSInteger)page pageSize:(NSInteger)pageSize jsonOption:(NSString * _Nullable)jsonOption NS_SWIFT_NAME(searchMusic(keyWord:page:pageSize:jsonOption:));
/**
* Preload a media file with specified parameters.
*
* @deprecated This method is deprecated. Use preload(songCode:) instead.
* @param songCode The identify of the media file that you want to play.
* @param jsonOption The ext param, default is null.
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (NSInteger)preloadWithSongCode:(NSInteger)songCode jsonOption:(NSString* _Nullable)jsonOption NS_SWIFT_NAME(preload(songCode:jsonOption:)) __attribute__((deprecated("Use preload(songCode:) instead.")));
/**
* Preload a media file with specified parameters.
*
* @param songCode The identify of the media file that you want to play.
* @return The request identification
*/
- (NSString *)preloadWithSongCode:(NSInteger)songCode NS_SWIFT_NAME(preload(songCode:));
/**
* Preload a media file with specified parameters.
*
* @param songCode The identify of the media file that you want to play.
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (NSInteger)isPreloadedWithSongCode:(NSInteger)songCode NS_SWIFT_NAME(isPreloaded(songCode:));
/**
* Remove a media file cache
*
* @param songCode The identifier of the media file that you want to play.
* @return
* - 0: Success; the cached media file is removed.
* - < 0: Failure.
*/
- (NSInteger)removeCacheWithSongCode:(NSInteger)songCode NS_SWIFT_NAME(removeCache(songCode:));
/**
* Get media cache files.
*
* @return The caches Array contains songCode and status of the music.
*/
- (NSArray *)getCaches NS_SWIFT_NAME(getCaches());
/**
* Get internal songCodeKey from songCode and jsonOption
*
* @param songCode The identifier of the media file.
* @param jsonOption An extention parameter. The default value is null. its a json-format string and the `key` and `value` can be customized according to your scenarios.
* @return
* - Internal songCode key, if the method call succeeds.
* - The number less than zero, if the method call fails.
*/
- (NSInteger)getInternalSongCode:(NSInteger)songCode jsonOption:(NSString * _Nullable)jsonOption NS_SWIFT_NAME(getInternalSongCode(songCode:jsonOption:));
/**
* Get lyric of the song. get result from the AgoraMusicContentCenterEventDelegate - (void)onLyricResult:(NSString*)requestId lyricUrl:(NSString*)lyricUrl; match the callback "requestId" parameter to get the request result.
*
* @param songCode The identify of the media file that you want to play.
* @param lyricType The type of the lyric file. may be 0:xml or 1:lrc.
* @return The request identification
*/
- (NSString *)getLyricWithSongCode:(NSInteger)songCode lyricType:(NSInteger)lyricType NS_SWIFT_NAME(getLyric(songCode:lyricType:));
/**
* Gets the metadata of a specific music. Once this method is called, the SDK triggers the onSongSimpleInfoResult callback to report the metadata of the music.
*
* @param songCode The identify of the media file that you want to play.
* @return The request identification
*/
- (NSString *)getSongSimpleInfoWithSongCode:(NSInteger)songCode NS_SWIFT_NAME(getSongSimpleInfo(songCode:));
/**
* If you want AgoraMusicContentCenterEventDelegate methods callback in the mainThread ,you should set enable YES. Default the delegate callback in subthread.
* - `NO`: (Default)Send the delegate callback in subthread.
* - `YES`: Send the delegate callback in mainthread.
*/
- (void)enableMainQueueDispatch:(BOOL)enabled;
/**
* Destroy the shared instance of AgoraMusicContentCenter
*
* @note If you call the method, you should call it brefore AgoraRtcEngineKit destroy
*/
+ (void)destroy;
#pragma mark - Unavailable Delegate Methods
#if TARGET_OS_IPHONE
- (void)onMusicChartsResult:(NSString *)requestId result:(NSArray<AgoraMusicChartInfo*> *)result errorCode:(AgoraMusicContentCenterStateReason)errorCode __attribute__((availability(ios,deprecated=7_0,message="Use onMusicChartsResult:result:statusCode: instead.")));
- (void)onMusicCollectionResult:(NSString *)requestId result:(AgoraMusicCollection *)result errorCode:(AgoraMusicContentCenterStateReason)errorCode __attribute__((availability(ios,deprecated=7_0,message="Use onMusicCollectionResult:result:statusCode: instead.")));
- (void)onLyricResult:(NSString*)requestId songCode:(NSInteger)songCode lyricUrl:(NSString* _Nullable)lyricUrl errorCode:(AgoraMusicContentCenterStateReason)errorCode __attribute__((availability(ios,deprecated=7_0,message="Use onLyricResult:songCode:lyricUrl:statusCode: instead.")));
- (void)onSongSimpleInfoResult:(NSString*)requestId songCode:(NSInteger)songCode simpleInfo:(NSString* _Nullable)simpleInfo errorCode:(AgoraMusicContentCenterStateReason)errorCode __attribute__((availability(ios,deprecated=7_0,message="Use onSongSimpleInfoResult:songCode:simpleInfo:statusCode: instead.")));
- (void)onPreLoadEvent:(NSString*)requestId songCode:(NSInteger)songCode percent:(NSInteger)percent lyricUrl:(NSString * _Nullable)lyricUrl state:(AgoraMusicContentCenterPreloadState)state errorCode:(AgoraMusicContentCenterStateReason)errorCode __attribute__((availability(ios,deprecated=7_0,message="Use onPreLoadEvent:songCode:percent:lyricUrl:status:statusCode: instead.")));
#endif
#if (!(TARGET_OS_IPHONE) && (TARGET_OS_MAC))
- (void)onMusicChartsResult:(NSString *)requestId result:(NSArray<AgoraMusicChartInfo*> *)result errorCode:(AgoraMusicContentCenterStateReason)errorCode __attribute__((availability(macos,deprecated=10_9,message="Use onMusicChartsResult:result:statusCode: instead.")));
- (void)onMusicCollectionResult:(NSString *)requestId result:(AgoraMusicCollection *)result errorCode:(AgoraMusicContentCenterStateReason)errorCode __attribute__((availability(macos,deprecated=10_9,message="Use onMusicCollectionResult:result:statusCode: instead.")));
- (void)onLyricResult:(NSString*)requestId songCode:(NSInteger)songCode lyricUrl:(NSString* _Nullable)lyricUrl errorCode:(AgoraMusicContentCenterStateReason)errorCode __attribute__((availability(macos,deprecated=10_9,message="Use onLyricResult:songCode:lyricUrl:statusCode: instead.")));
- (void)onSongSimpleInfoResult:(NSString*)requestId songCode:(NSInteger)songCode simpleInfo:(NSString* _Nullable)simpleInfo errorCode:(AgoraMusicContentCenterStateReason)errorCode __attribute__((availability(macos,deprecated=10_9,message="Use onSongSimpleInfoResult:songCode:simpleInfo:statusCode: instead.")));
- (void)onPreLoadEvent:(NSString*)requestId songCode:(NSInteger)songCode percent:(NSInteger)percent lyricUrl:(NSString * _Nullable)lyricUrl state:(AgoraMusicContentCenterPreloadState)state errorCode:(AgoraMusicContentCenterStateReason)errorCode __attribute__((availability(macos,deprecated=10_9,message="Use onPreLoadEvent:songCode:percent:lyricUrl:status:statusCode: instead.")));
#endif
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,891 @@
// Copyright (c) 2019 Agora.io. All rights reserved
// This program is confidential and proprietary to Agora.io.
// And may not be copied, reproduced, modified, disclosed to others, published
// or used, in whole or in part, without the express prior written permission
// of Agora.io.
#pragma once
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
#include <type_traits>
#endif
#include <utility>
#ifndef CONSTEXPR
#if __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)
#define CONSTEXPR constexpr
#else
#define CONSTEXPR
#endif
#endif // !CONSTEXPR
#ifndef NOEXCEPT
#if __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)
#define NOEXCEPT(Expr) noexcept(Expr)
#else
#define NOEXCEPT(Expr)
#endif
#endif // !NOEXCEPT
namespace agora {
// Specification:
// http://en.cppreference.com/w/cpp/utility/optional/in_place_t
struct in_place_t {};
// Specification:
// http://en.cppreference.com/w/cpp/utility/optional/nullopt_t
struct nullopt_t {
CONSTEXPR explicit nullopt_t(int) {}
};
// Specification:
// http://en.cppreference.com/w/cpp/utility/optional/in_place
/*CONSTEXPR*/ const in_place_t in_place = {};
// Specification:
// http://en.cppreference.com/w/cpp/utility/optional/nullopt
/*CONSTEXPR*/ const nullopt_t nullopt(0);
// Forward declaration, which is refered by following helpers.
template <typename T>
class Optional;
namespace internal {
template <typename T>
struct OptionalStorageBase {
// Initializing |empty_| here instead of using default member initializing
// to avoid errors in g++ 4.8.
CONSTEXPR OptionalStorageBase() : is_populated_(false), empty_('\0') {}
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
template <class... Args>
CONSTEXPR explicit OptionalStorageBase(in_place_t, Args&&... args)
: is_populated_(true), value_(std::forward<Args>(args)...) {}
#else
CONSTEXPR explicit OptionalStorageBase(in_place_t, const T& _value)
: is_populated_(true), value_(_value) {}
#endif
// When T is not trivially destructible we must call its
// destructor before deallocating its memory.
// Note that this hides the (implicitly declared) move constructor, which
// would be used for constexpr move constructor in OptionalStorage<T>.
// It is needed iff T is trivially move constructible. However, the current
// is_trivially_{copy,move}_constructible implementation requires
// is_trivially_destructible (which looks a bug, cf:
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452 and
// http://cplusplus.github.io/LWG/lwg-active.html#2116), so it is not
// necessary for this case at the moment. Please see also the destructor
// comment in "is_trivially_destructible = true" specialization below.
~OptionalStorageBase() {
if (is_populated_)
value_.~T();
}
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
template <class... Args>
void Init(Args&&... args) {
::new (&value_) T(std::forward<Args>(args)...);
is_populated_ = true;
}
#else
void Init(const T& _value) {
::new (&value_) T(_value);
is_populated_ = true;
}
#endif
bool is_populated_;
union {
// |empty_| exists so that the union will always be initialized, even when
// it doesn't contain a value. Union members must be initialized for the
// constructor to be 'constexpr'.
char empty_;
T value_;
};
};
// Implement conditional constexpr copy and move constructors. These are
// constexpr if is_trivially_{copy,move}_constructible<T>::value is true
// respectively. If each is true, the corresponding constructor is defined as
// "= default;", which generates a constexpr constructor (In this case,
// the condition of constexpr-ness is satisfied because the base class also has
// compiler generated constexpr {copy,move} constructors). Note that
// placement-new is prohibited in constexpr.
template <typename T>
struct OptionalStorage : OptionalStorageBase<T> {
// This is no trivially {copy,move} constructible case. Other cases are
// defined below as specializations.
// Accessing the members of template base class requires explicit
// declaration.
using OptionalStorageBase<T>::is_populated_;
using OptionalStorageBase<T>::value_;
using OptionalStorageBase<T>::Init;
// Inherit constructors (specifically, the in_place constructor).
//using OptionalStorageBase<T>::OptionalStorageBase;
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
template <class... Args>
CONSTEXPR explicit OptionalStorage(in_place_t in_place, Args&&... args)
: OptionalStorageBase<T>(in_place, std::forward<Args>(args)...) {}
#else
CONSTEXPR explicit OptionalStorage(in_place_t in_place, const T& _value)
: OptionalStorageBase<T>(in_place, _value) {}
#endif
// User defined constructor deletes the default constructor.
// Define it explicitly.
OptionalStorage() {}
OptionalStorage(const OptionalStorage& other) {
if (other.is_populated_)
Init(other.value_);
}
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
OptionalStorage(OptionalStorage&& other) NOEXCEPT(std::is_nothrow_move_constructible<T>::value) {
if (other.is_populated_)
Init(std::move(other.value_));
}
#endif
};
// Base class to support conditionally usable copy-/move- constructors
// and assign operators.
template <typename T>
class OptionalBase {
// This class provides implementation rather than public API, so everything
// should be hidden. Often we use composition, but we cannot in this case
// because of C++ language restriction.
protected:
CONSTEXPR OptionalBase() {}
CONSTEXPR OptionalBase(const OptionalBase& other) : storage_(other.storage_) {}
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
CONSTEXPR OptionalBase(OptionalBase&& other) : storage_(std::move(other.storage_)) {}
template <class... Args>
CONSTEXPR explicit OptionalBase(in_place_t, Args&&... args)
: storage_(in_place, std::forward<Args>(args)...) {}
#else
CONSTEXPR explicit OptionalBase(in_place_t, const T& _value)
: storage_(in_place, _value) {}
#endif
// Implementation of converting constructors.
template <typename U>
explicit OptionalBase(const OptionalBase<U>& other) {
if (other.storage_.is_populated_)
storage_.Init(other.storage_.value_);
}
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
template <typename U>
explicit OptionalBase(OptionalBase<U>&& other) {
if (other.storage_.is_populated_)
storage_.Init(std::move(other.storage_.value_));
}
#endif
~OptionalBase() {}
OptionalBase& operator=(const OptionalBase& other) {
CopyAssign(other);
return *this;
}
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
OptionalBase& operator=(OptionalBase&& other) NOEXCEPT(
std::is_nothrow_move_assignable<T>::value &&
std::is_nothrow_move_constructible<T>::value) {
MoveAssign(std::move(other));
return *this;
}
#endif
template <typename U>
void CopyAssign(const OptionalBase<U>& other) {
if (other.storage_.is_populated_)
InitOrAssign(other.storage_.value_);
else
FreeIfNeeded();
}
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
template <typename U>
void MoveAssign(OptionalBase<U>&& other) {
if (other.storage_.is_populated_)
InitOrAssign(std::move(other.storage_.value_));
else
FreeIfNeeded();
}
#endif
template <typename U>
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
void InitOrAssign(U&& value) {
if (storage_.is_populated_)
storage_.value_ = std::forward<U>(value);
else
storage_.Init(std::forward<U>(value));
}
#else
void InitOrAssign(const U& value) {
if (storage_.is_populated_)
storage_.value_ = value;
else
storage_.Init(value);
}
#endif
void FreeIfNeeded() {
if (!storage_.is_populated_)
return;
storage_.value_.~T();
storage_.is_populated_ = false;
}
// For implementing conversion, allow access to other typed OptionalBase
// class.
template <typename U>
friend class OptionalBase;
OptionalStorage<T> storage_;
};
// The following {Copy,Move}{Constructible,Assignable} structs are helpers to
// implement constructor/assign-operator overloading. Specifically, if T is
// is not movable but copyable, Optional<T>'s move constructor should not
// participate in overload resolution. This inheritance trick implements that.
template <bool is_copy_constructible>
struct CopyConstructible {};
template <>
struct CopyConstructible<false> {
CONSTEXPR CopyConstructible() {}
CopyConstructible& operator=(const CopyConstructible&) { return *this; }
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
CONSTEXPR CopyConstructible(CopyConstructible&&) {}
CopyConstructible& operator=(CopyConstructible&&) { return *this; }
#endif
private:
CONSTEXPR CopyConstructible(const CopyConstructible&);
};
template <bool is_move_constructible>
struct MoveConstructible {};
template <>
struct MoveConstructible<false> {
CONSTEXPR MoveConstructible() {}
CONSTEXPR MoveConstructible(const MoveConstructible&) {}
MoveConstructible& operator=(const MoveConstructible&) { return *this; }
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
MoveConstructible& operator=(MoveConstructible&&) { return *this; }
private:
CONSTEXPR MoveConstructible(MoveConstructible&&);
#endif
};
template <bool is_copy_assignable>
struct CopyAssignable {};
template <>
struct CopyAssignable<false> {
CONSTEXPR CopyAssignable() {}
CONSTEXPR CopyAssignable(const CopyAssignable&) {}
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
CONSTEXPR CopyAssignable(CopyAssignable&&) {}
CopyAssignable& operator=(CopyAssignable&&) { return *this; }
#endif
private:
CopyAssignable& operator=(const CopyAssignable&);
};
template <bool is_move_assignable>
struct MoveAssignable {};
template <>
struct MoveAssignable<false> {
CONSTEXPR MoveAssignable() {}
CONSTEXPR MoveAssignable(const MoveAssignable&) {}
MoveAssignable& operator=(const MoveAssignable&) { return *this; }
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
CONSTEXPR MoveAssignable(MoveAssignable&&) {}
private:
MoveAssignable& operator=(MoveAssignable&&);
#endif
};
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
// Helper to conditionally enable converting constructors and assign operators.
template <typename T, typename U>
struct IsConvertibleFromOptional
: std::integral_constant<
bool,
std::is_constructible<T, Optional<U>&>::value ||
std::is_constructible<T, const Optional<U>&>::value ||
std::is_constructible<T, Optional<U>&&>::value ||
std::is_constructible<T, const Optional<U>&&>::value ||
std::is_convertible<Optional<U>&, T>::value ||
std::is_convertible<const Optional<U>&, T>::value ||
std::is_convertible<Optional<U>&&, T>::value ||
std::is_convertible<const Optional<U>&&, T>::value> {};
template <typename T, typename U>
struct IsAssignableFromOptional
: std::integral_constant<
bool,
IsConvertibleFromOptional<T, U>::value ||
std::is_assignable<T&, Optional<U>&>::value ||
std::is_assignable<T&, const Optional<U>&>::value ||
std::is_assignable<T&, Optional<U>&&>::value ||
std::is_assignable<T&, const Optional<U>&&>::value> {};
// Forward compatibility for C++17.
// Introduce one more deeper nested namespace to avoid leaking using std::swap.
namespace swappable_impl {
using std::swap;
struct IsSwappableImpl {
// Tests if swap can be called. Check<T&>(0) returns true_type iff swap
// is available for T. Otherwise, Check's overload resolution falls back
// to Check(...) declared below thanks to SFINAE, so returns false_type.
template <typename T>
static auto Check(int)
-> decltype(swap(std::declval<T>(), std::declval<T>()), std::true_type());
template <typename T>
static std::false_type Check(...);
};
} // namespace swappable_impl
template <typename T>
struct IsSwappable : decltype(swappable_impl::IsSwappableImpl::Check<T&>(0)) {};
#endif
} // namespace internal
// On Windows, by default, empty-base class optimization does not work,
// which means even if the base class is empty struct, it still consumes one
// byte for its body. __declspec(empty_bases) enables the optimization.
// cf)
// https://blogs.msdn.microsoft.com/vcblog/2016/03/30/optimizing-the-layout-of-empty-base-classes-in-vs2015-update-2-3/
#if defined(_WIN32)
#define OPTIONAL_DECLSPEC_EMPTY_BASES __declspec(empty_bases)
#else
#define OPTIONAL_DECLSPEC_EMPTY_BASES
#endif
// Optional is a Chromium version of the C++17 optional class:
// std::optional documentation:
// http://en.cppreference.com/w/cpp/utility/optional
// Chromium documentation:
// https://chromium.googlesource.com/chromium/src/+/master/docs/optional.md
//
// These are the differences between the specification and the implementation:
// - Constructors do not use 'constexpr' as it is a C++14 extension.
// - 'constexpr' might be missing in some places for reasons specified locally.
// - No exceptions are thrown, because they are banned from Chromium.
// Marked noexcept for only move constructor and move assign operators.
// - All the non-members are in the 'base' namespace instead of 'std'.
//
// Note that T cannot have a constructor T(Optional<T>) etc. Optional<T> checks
// T's constructor (specifically via IsConvertibleFromOptional), and in the
// check whether T can be constructible from Optional<T>, which is recursive
// so it does not work. As of Feb 2018, std::optional C++17 implementation in
// both clang and gcc has same limitation. MSVC SFINAE looks to have different
// behavior, but anyway it reports an error, too.
template <typename T>
class OPTIONAL_DECLSPEC_EMPTY_BASES Optional
: public internal::OptionalBase<T>
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
, public internal::CopyConstructible<std::is_copy_constructible<T>::value>,
public internal::MoveConstructible<std::is_move_constructible<T>::value>,
public internal::CopyAssignable<std::is_copy_constructible<T>::value &&
std::is_copy_assignable<T>::value>,
public internal::MoveAssignable<std::is_move_constructible<T>::value &&
std::is_move_assignable<T>::value>
#endif
{
public:
#undef OPTIONAL_DECLSPEC_EMPTY_BASES
typedef T value_type;
// Defer default/copy/move constructor implementation to OptionalBase.
CONSTEXPR Optional() {}
CONSTEXPR Optional(const Optional& other) : internal::OptionalBase<T>(other) {}
CONSTEXPR Optional(nullopt_t) {} // NOLINT(runtime/explicit)
// Converting copy constructor. "explicit" only if
// std::is_convertible<const U&, T>::value is false. It is implemented by
// declaring two almost same constructors, but that condition in enable_if_t
// is different, so that either one is chosen, thanks to SFINAE.
template <typename U>
Optional(const Optional<U>& other) : internal::OptionalBase<T>(other) {}
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
// Converting move constructor. Similar to converting copy constructor,
// declaring two (explicit and non-explicit) constructors.
template <typename U>
Optional(Optional<U>&& other) : internal::OptionalBase<T>(std::move(other)) {}
template <class... Args>
CONSTEXPR explicit Optional(in_place_t, Args&&... args)
: internal::OptionalBase<T>(in_place, std::forward<Args>(args)...) {}
template <class U, class... Args>
CONSTEXPR explicit Optional(in_place_t,
std::initializer_list<U> il,
Args&&... args)
: internal::OptionalBase<T>(in_place, il, std::forward<Args>(args)...) {}
#else
CONSTEXPR explicit Optional(in_place_t, const T& _value)
: internal::OptionalBase<T>(in_place, _value) {}
template <class U>
CONSTEXPR explicit Optional(in_place_t,
const U il[],
const T& _value)
: internal::OptionalBase<T>(in_place, il, _value) {}
#endif
// Forward value constructor. Similar to converting constructors,
// conditionally explicit.
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
template <typename U = value_type>
CONSTEXPR Optional(U&& value)
: internal::OptionalBase<T>(in_place, std::forward<U>(value)) {}
#else
template <typename U>
CONSTEXPR Optional(const U& value)
: internal::OptionalBase<T>(in_place, value) {}
#endif
~Optional() {}
// Defer copy-/move- assign operator implementation to OptionalBase.
Optional& operator=(const Optional& other) {
if (&other == this) {
return *this;
}
internal::OptionalBase<T>::operator=(other);
return *this;
}
Optional& operator=(nullopt_t) {
FreeIfNeeded();
return *this;
}
// Perfect-forwarded assignment.
template <typename U>
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
Optional& operator=(U&& value) {
InitOrAssign(std::forward<U>(value));
return *this;
}
#else
Optional& operator=(const U& value) {
InitOrAssign(value);
return *this;
}
#endif
// Copy assign the state of other.
template <typename U>
Optional& operator=(const Optional<U>& other) {
CopyAssign(other);
return *this;
}
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
// Move assign the state of other.
template <typename U>
Optional& operator=(Optional<U>&& other) {
MoveAssign(std::move(other));
return *this;
}
#endif
const T* operator->() const {
return &storage_.value_;
}
T* operator->() {
return &storage_.value_;
}
const T& operator*() const {
return storage_.value_;
}
T& operator*() {
return storage_.value_;
}
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
CONSTEXPR explicit operator bool() const { return storage_.is_populated_; }
#else
CONSTEXPR operator bool() const { return storage_.is_populated_; }
#endif
CONSTEXPR bool has_value() const { return storage_.is_populated_; }
#if 1
const T& value() const {
return storage_.value_;
}
template <class U>
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
CONSTEXPR T value_or(U&& default_value) const {
// TODO(mlamouri): add the following assert when possible:
// static_assert(std::is_copy_constructible<T>::value,
// "T must be copy constructible");
static_assert(std::is_convertible<U, T>::value,
"U must be convertible to T");
return storage_.is_populated_
? value()
: static_cast<T>(std::forward<U>(default_value));
}
#else
CONSTEXPR T value_or(const U& default_value) const {
return storage_.is_populated_
? value()
: static_cast<T>(default_value);
}
#endif
#else
const T& value() const & {
return storage_.value_;
}
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
const T&& value() const && {
return std::move(storage_.value_);
}
#endif
template <class U>
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
CONSTEXPR T value_or(U&& default_value) const & {
// TODO(mlamouri): add the following assert when possible:
// static_assert(std::is_copy_constructible<T>::value,
// "T must be copy constructible");
static_assert(std::is_convertible<U, T>::value,
"U must be convertible to T");
return storage_.is_populated_
? value()
: static_cast<T>(std::forward<U>(default_value));
}
#else
CONSTEXPR T value_or(const U& default_value) const & {
// TODO(mlamouri): add the following assert when possible:
// static_assert(std::is_copy_constructible<T>::value,
// "T must be copy constructible");
static_assert(std::is_convertible<U, T>::value,
"U must be convertible to T");
return storage_.is_populated_
? value()
: static_cast<T>(default_value);
}
#endif
template <class U>
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
CONSTEXPR T value_or(U&& default_value) const && {
// TODO(mlamouri): add the following assert when possible:
// static_assert(std::is_move_constructible<T>::value,
// "T must be move constructible");
static_assert(std::is_convertible<U, T>::value,
"U must be convertible to T");
return storage_.is_populated_
? std::move(value())
: static_cast<T>(std::forward<U>(default_value));
}
#endif
#endif // 1
void swap(Optional& other) {
if (!storage_.is_populated_ && !other.storage_.is_populated_)
return;
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
if (storage_.is_populated_ != other.storage_.is_populated_) {
if (storage_.is_populated_) {
other.storage_.Init(std::move(storage_.value_));
FreeIfNeeded();
} else {
storage_.Init(std::move(other.storage_.value_));
other.FreeIfNeeded();
}
return;
}
#endif
using std::swap;
swap(**this, *other);
}
void reset() { FreeIfNeeded(); }
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
template <class... Args>
T& emplace(Args&&... args) {
FreeIfNeeded();
storage_.Init(std::forward<Args>(args)...);
return storage_.value_;
}
template <class U, class... Args>
T& emplace(std::initializer_list<U> il, Args&&... args) {
FreeIfNeeded();
storage_.Init(il, std::forward<Args>(args)...);
return storage_.value_;
}
#else
T& emplace(const T& _value) {
FreeIfNeeded();
storage_.Init(_value);
return storage_.value_;
}
template <class U>
T& emplace(const U il[], const T& _value) {
FreeIfNeeded();
storage_.Init(il, _value);
return storage_.value_;
}
#endif
private:
// Accessing template base class's protected member needs explicit
// declaration to do so.
using internal::OptionalBase<T>::CopyAssign;
using internal::OptionalBase<T>::FreeIfNeeded;
using internal::OptionalBase<T>::InitOrAssign;
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
using internal::OptionalBase<T>::MoveAssign;
#endif
using internal::OptionalBase<T>::storage_;
};
// Here after defines comparation operators. The definition follows
// http://en.cppreference.com/w/cpp/utility/optional/operator_cmp
// while bool() casting is replaced by has_value() to meet the chromium
// style guide.
template <class T, class U>
bool operator==(const Optional<T>& lhs, const Optional<U>& rhs) {
if (lhs.has_value() != rhs.has_value())
return false;
if (!lhs.has_value())
return true;
return *lhs == *rhs;
}
template <class T, class U>
bool operator!=(const Optional<T>& lhs, const Optional<U>& rhs) {
if (lhs.has_value() != rhs.has_value())
return true;
if (!lhs.has_value())
return false;
return *lhs != *rhs;
}
template <class T, class U>
bool operator<(const Optional<T>& lhs, const Optional<U>& rhs) {
if (!rhs.has_value())
return false;
if (!lhs.has_value())
return true;
return *lhs < *rhs;
}
template <class T, class U>
bool operator<=(const Optional<T>& lhs, const Optional<U>& rhs) {
if (!lhs.has_value())
return true;
if (!rhs.has_value())
return false;
return *lhs <= *rhs;
}
template <class T, class U>
bool operator>(const Optional<T>& lhs, const Optional<U>& rhs) {
if (!lhs.has_value())
return false;
if (!rhs.has_value())
return true;
return *lhs > *rhs;
}
template <class T, class U>
bool operator>=(const Optional<T>& lhs, const Optional<U>& rhs) {
if (!rhs.has_value())
return true;
if (!lhs.has_value())
return false;
return *lhs >= *rhs;
}
template <class T>
CONSTEXPR bool operator==(const Optional<T>& opt, nullopt_t) {
return !opt;
}
template <class T>
CONSTEXPR bool operator==(nullopt_t, const Optional<T>& opt) {
return !opt;
}
template <class T>
CONSTEXPR bool operator!=(const Optional<T>& opt, nullopt_t) {
return opt.has_value();
}
template <class T>
CONSTEXPR bool operator!=(nullopt_t, const Optional<T>& opt) {
return opt.has_value();
}
template <class T>
CONSTEXPR bool operator<(const Optional<T>& , nullopt_t) {
return false;
}
template <class T>
CONSTEXPR bool operator<(nullopt_t, const Optional<T>& opt) {
return opt.has_value();
}
template <class T>
CONSTEXPR bool operator<=(const Optional<T>& opt, nullopt_t) {
return !opt;
}
template <class T>
CONSTEXPR bool operator<=(nullopt_t, const Optional<T>& ) {
return true;
}
template <class T>
CONSTEXPR bool operator>(const Optional<T>& opt, nullopt_t) {
return opt.has_value();
}
template <class T>
CONSTEXPR bool operator>(nullopt_t, const Optional<T>& ) {
return false;
}
template <class T>
CONSTEXPR bool operator>=(const Optional<T>& , nullopt_t) {
return true;
}
template <class T>
CONSTEXPR bool operator>=(nullopt_t, const Optional<T>& opt) {
return !opt;
}
template <class T, class U>
CONSTEXPR bool operator==(const Optional<T>& opt, const U& value) {
return opt.has_value() ? *opt == value : false;
}
template <class T, class U>
CONSTEXPR bool operator==(const U& value, const Optional<T>& opt) {
return opt.has_value() ? value == *opt : false;
}
template <class T, class U>
CONSTEXPR bool operator!=(const Optional<T>& opt, const U& value) {
return opt.has_value() ? *opt != value : true;
}
template <class T, class U>
CONSTEXPR bool operator!=(const U& value, const Optional<T>& opt) {
return opt.has_value() ? value != *opt : true;
}
template <class T, class U>
CONSTEXPR bool operator<(const Optional<T>& opt, const U& value) {
return opt.has_value() ? *opt < value : true;
}
template <class T, class U>
CONSTEXPR bool operator<(const U& value, const Optional<T>& opt) {
return opt.has_value() ? value < *opt : false;
}
template <class T, class U>
CONSTEXPR bool operator<=(const Optional<T>& opt, const U& value) {
return opt.has_value() ? *opt <= value : true;
}
template <class T, class U>
CONSTEXPR bool operator<=(const U& value, const Optional<T>& opt) {
return opt.has_value() ? value <= *opt : false;
}
template <class T, class U>
CONSTEXPR bool operator>(const Optional<T>& opt, const U& value) {
return opt.has_value() ? *opt > value : false;
}
template <class T, class U>
CONSTEXPR bool operator>(const U& value, const Optional<T>& opt) {
return opt.has_value() ? value > *opt : true;
}
template <class T, class U>
CONSTEXPR bool operator>=(const Optional<T>& opt, const U& value) {
return opt.has_value() ? *opt >= value : false;
}
template <class T, class U>
CONSTEXPR bool operator>=(const U& value, const Optional<T>& opt) {
return opt.has_value() ? value >= *opt : true;
}
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
template <class T, class... Args>
CONSTEXPR Optional<T> make_optional(Args&&... args) {
return Optional<T>(in_place, std::forward<Args>(args)...);
}
template <class T, class U, class... Args>
CONSTEXPR Optional<T> make_optional(std::initializer_list<U> il,
Args&&... args) {
return Optional<T>(in_place, il, std::forward<Args>(args)...);
}
#endif
// Partial specialization for a function template is not allowed. Also, it is
// not allowed to add overload function to std namespace, while it is allowed
// to specialize the template in std. Thus, swap() (kind of) overloading is
// defined in base namespace, instead.
template <class T>
void swap(Optional<T>& lhs, Optional<T>& rhs) {
lhs.swap(rhs);
}
} // namespace agora
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
namespace std {
template <class T>
struct hash<agora::Optional<T> > {
size_t operator()(const agora::Optional<T>& opt) const {
return opt == agora::nullopt ? 0 : std::hash<T>()(*opt);
}
};
} // namespace std
#endif
#undef CONSTEXPR
#undef NOEXCEPT

View File

@@ -0,0 +1,137 @@
// Copyright (c) 2020 Agora.io. All rights reserved
// This program is confidential and proprietary to Agora.io.
// And may not be copied, reproduced, modified, disclosed to others, published
// or used, in whole or in part, without the express prior written permission
// of Agora.io.
#pragma once
#ifndef __AGORA_REF_COUNTED_OBJECT_H__
#define __AGORA_REF_COUNTED_OBJECT_H__
#endif
#if defined(__AGORA_REF_COUNTED_OBJECT_INTERNAL_H__)
#error AgoraRefCountedObject is deprected now, its only purpose is for API compatiable.
#endif
#include "AgoraRefPtr.h"
#include "AgoraAtomicOps.h"
#ifndef OPTIONAL_REFCOUNTRELEASESTATUS_SPECIFIER
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
#define OPTIONAL_REFCOUNTRELEASESTATUS_SPECIFIER agora::RefCountReleaseStatus::
#else
#define OPTIONAL_REFCOUNTRELEASESTATUS_SPECIFIER
#endif
#endif
namespace agora {
class RefCounter {
public:
explicit RefCounter(int ref_count) : ref_count_(ref_count) {}
void IncRef() { AtomicOps::Increment(&ref_count_); }
/**
* Returns true if this was the last reference, and the resource protected by
* the reference counter can be deleted.
*/
agora::RefCountReleaseStatus DecRef() {
return (AtomicOps::Decrement(&ref_count_) == 0
? OPTIONAL_REFCOUNTRELEASESTATUS_SPECIFIER kDroppedLastRef
: OPTIONAL_REFCOUNTRELEASESTATUS_SPECIFIER kOtherRefsRemained);
}
/**
* Return whether the reference count is one. If the reference count is used
* in the conventional way, a reference count of 1 implies that the current
* thread owns the reference and no other thread shares it. This call performs
* the test for a reference count of one, and performs the memory barrier
* needed for the owning thread to act on the resource protected by the
* reference counter, knowing that it has exclusive access.
*/
bool HasOneRef() const { return (AtomicOps::AcquireLoad(&ref_count_) == 1); }
private:
RefCounter();
private:
volatile int ref_count_;
};
/**
* Agora sample code for wrapping a class that needs to inherit from RefCountInterface in order
* to be held by agora::agora_refptr
* Usage:
* agora::agora_refptr<TypeName> ptr = new RefCountedObject<TypeName>(Arg1, Arg2, ...);
*/
template <class T>
class RefCountedObject : public T {
public:
RefCountedObject(): ref_count_(0) {}
template <class P0>
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
explicit RefCountedObject(P0&& p0) : T(std::forward<P0>(p0)), ref_count_(0) {}
#else
explicit RefCountedObject(const P0& p0) : T(p0), ref_count_(0) {}
#endif
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
template <class P0, class P1, class... Args>
RefCountedObject(P0&& p0, P1&& p1, Args&&... args)
: T(std::forward<P0>(p0),
std::forward<P1>(p1),
std::forward<Args>(args)...),
ref_count_(0) {}
#endif
virtual void AddRef() const { ref_count_.IncRef(); }
virtual agora::RefCountReleaseStatus Release() const {
const agora::RefCountReleaseStatus status = ref_count_.DecRef();
if (status == OPTIONAL_REFCOUNTRELEASESTATUS_SPECIFIER kDroppedLastRef) {
delete this;
}
return status;
}
/**
* Return whether the reference count is one. If the reference count is used
* in the conventional way, a reference count of 1 implies that the current
* thread owns the reference and no other thread shares it. This call
* performs the test for a reference count of one, and performs the memory
* barrier needed for the owning thread to act on the object, knowing that it
* has exclusive access to the object.
*/
virtual bool HasOneRef() const { return ref_count_.HasOneRef(); }
protected:
virtual ~RefCountedObject() {}
private:
RefCountedObject(const RefCountedObject&);
RefCountedObject& operator=(const RefCountedObject&);
protected:
mutable agora::RefCounter ref_count_;
};
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
template <typename T, typename... types>
inline agora_refptr<T> make_refptr(types&&... args) {
return agora_refptr<T>(new RefCountedObject<T>(std::forward<types>(args)...));
}
#else
template <typename T>
inline agora_refptr<T> make_refptr() {
return agora_refptr<T>(new RefCountedObject<T>());
}
template <typename T, typename P0>
inline agora_refptr<T> make_refptr(const P0& p0) {
return agora_refptr<T>(new RefCountedObject<T>(p0));
}
#endif
} // namespace agora

View File

@@ -0,0 +1,156 @@
// Copyright (c) 2019 Agora.io. All rights reserved
// This program is confidential and proprietary to Agora.io.
// And may not be copied, reproduced, modified, disclosed to others, published
// or used, in whole or in part, without the express prior written permission
// of Agora.io.
#pragma once
#include <memory>
#if !(__cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800))
#include <cstddef>
#endif
#ifndef OPTIONAL_ENUM_CLASS
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
#define OPTIONAL_ENUM_CLASS enum class
#else
#define OPTIONAL_ENUM_CLASS enum
#endif
#endif
namespace agora {
OPTIONAL_ENUM_CLASS RefCountReleaseStatus { kDroppedLastRef, kOtherRefsRemained };
// Interfaces where refcounting is part of the public api should
// inherit this abstract interface. The implementation of these
// methods is usually provided by the RefCountedObject template class,
// applied as a leaf in the inheritance tree.
class RefCountInterface {
public:
virtual void AddRef() const = 0;
virtual RefCountReleaseStatus Release() const = 0;
virtual bool HasOneRef() const = 0;
// Non-public destructor, because Release() has exclusive responsibility for
// destroying the object.
protected:
virtual ~RefCountInterface() {}
};
template <class T>
class agora_refptr {
public:
agora_refptr() : ptr_(NULL) {}
agora_refptr(T* p) : ptr_(p) {
if (ptr_) ptr_->AddRef();
}
template<typename U>
agora_refptr(U* p) : ptr_(p) {
if (ptr_) ptr_->AddRef();
}
agora_refptr(const agora_refptr<T>& r) : ptr_(r.get()) {
if (ptr_) ptr_->AddRef();
}
template <typename U>
agora_refptr(const agora_refptr<U>& r) : ptr_(r.get()) {
if (ptr_) ptr_->AddRef();
}
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
agora_refptr(agora_refptr<T>&& r) : ptr_(r.move()) {}
template <typename U>
agora_refptr(agora_refptr<U>&& r) : ptr_(r.move()) {}
#endif
~agora_refptr() {
reset();
}
T* get() const { return ptr_; }
operator bool() const { return (ptr_ != NULL); }
T* operator->() const { return ptr_; }
T& operator*() const { return *ptr_; }
// Returns the (possibly null) raw pointer, and makes the agora_refptr hold a
// null pointer, all without touching the reference count of the underlying
// pointed-to object. The object is still reference counted, and the caller of
// move() is now the proud owner of one reference, so it is responsible for
// calling Release() once on the object when no longer using it.
T* move() {
T* retVal = ptr_;
ptr_ = NULL;
return retVal;
}
agora_refptr<T>& operator=(T* p) {
if (ptr_ == p) return *this;
if (p) p->AddRef();
if (ptr_) ptr_->Release();
ptr_ = p;
return *this;
}
agora_refptr<T>& operator=(const agora_refptr<T>& r) {
return *this = r.get();
}
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
agora_refptr<T>& operator=(agora_refptr<T>&& r) {
agora_refptr<T>(std::move(r)).swap(*this);
return *this;
}
template <typename U>
agora_refptr<T>& operator=(agora_refptr<U>&& r) {
agora_refptr<T>(std::move(r)).swap(*this);
return *this;
}
#endif
// For working with std::find()
bool operator==(const agora_refptr<T>& r) const { return ptr_ == r.ptr_; }
// For working with std::set
bool operator<(const agora_refptr<T>& r) const { return ptr_ < r.ptr_; }
void swap(T** pp) {
T* p = ptr_;
ptr_ = *pp;
*pp = p;
}
void swap(agora_refptr<T>& r) { swap(&r.ptr_); }
void reset() {
if (ptr_) {
ptr_->Release();
ptr_ = NULL;
}
}
protected:
T* ptr_;
};
} // namespace agora
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
namespace std {
template <typename T>
struct hash<agora::agora_refptr<T>> {
std::size_t operator()(const agora::agora_refptr<T>& k) const {
return reinterpret_cast<size_t>(k.get());
}
};
} // namespace std
#endif

View File

@@ -0,0 +1,43 @@
//
// Copyright (c) 2020 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "AgoraObjects.h"
@protocol AgoraAudioSpectrumDelegate <NSObject>
@optional
/**
* Reports the audio spectrum of audio recording.
*
* This callback reports the audio spectrum data of the audio recording at the moment
* in the channel.
*
* You can set the time interval of this callback using "enableAudioSpectrumMonitor".
*
* @param audioSpectrumData The audio spectrum data of audio recording.
* - true: Processed.
* - false: Not processed.
*/
- (BOOL)onLocalAudioSpectrum:(NSArray<NSNumber *> * _Nullable)audioSpectrumData NS_SWIFT_NAME(onLocalAudioSpectrum(_:));
/**
* Reports the audio spectrum of remote user.
*
* This callback reports the IDs and audio spectrum data of the loudest speakers at the moment
* in the channel.
*
* You can set the time interval of this callback using "enableAudioSpectrumMonitor".
*
* @param AudioSpectrumInfo The pointer to AudioSpectrumInfo, which is an array containing
* the user ID and audio spectrum data for each speaker.
* - This array contains the following members:
* - `uid`, which is the UID of each remote speaker
* - `audioSpectrumData`, which reports the audio spectrum of each remote speaker.
* - `spectrumDataLength`, the length of audio spectrum data.
* - true: Processed.
* - false: Not processed.
*/
- (BOOL)onRemoteAudioSpectrum:(NSArray<AgoraAudioSpectrumInfo *> * _Nullable)AudioSpectrumInfo NS_SWIFT_NAME(onRemoteAudioSpectrum(_:));
@end

View File

@@ -0,0 +1,34 @@
//
// AgoraRtcKit.h
// AgoraRtcKit
//
// Copyright (c) 2018 Agora. All rights reserved.
//
#import <AgoraRtcKit/AgoraConstants.h>
#import <AgoraRtcKit/AgoraEnumerates.h>
#import <AgoraRtcKit/AgoraObjects.h>
#import <AgoraRtcKit/AgoraRtcEngineKit.h>
#import <AgoraRtcKit/AgoraRtcEngineKitEx.h>
#import <AgoraRtcKit/AgoraRtcEngineDelegate.h>
#import <AgoraRtcKit/AgoraAudioFrameDelegate.h>
#import <AgoraRtcKit/AgoraAudioEncodedFrameDelegate.h>
#import <AgoraRtcKit/AgoraRtcAudioSpectrumDelegate.h>
#import <AgoraRtcKit/AgoraVideoFrameDelegate.h>
#import <AgoraRtcKit/AgoraFaceInfoDelegate.h>
#import <AgoraRtcKit/AgoraEncodedVideoFrameDelegate.h>
#import <AgoraRtcKit/AgoraRtcMediaPlayerProtocol.h>
#import <AgoraRtcKit/AgoraRtcMediaPlayerDelegate.h>
#import <AgoraRtcKit/AgoraRtcMediaPlayerAudioFrameDelegate.h>
#import <AgoraRtcKit/AgoraRtcMediaPlayerVideoFrameDelegate.h>
#import <AgoraRtcKit/AgoraH265TranscoderProtocol.h>
#import <AgoraRtcKit/AgoraH265TranscoderDelegate.h>
#import <AgoraRtcKit/AgoraMediaRecorder.h>
#import <AgoraRtcKit/AgoraMediaRecorderDelegate.h>
#import <AgoraRtcKit/AgoraMediaMetadataDelegate.h>
#import <AgoraRtcKit/AgoraMediaMetadataDataSource.h>
#import <AgoraRtcKit/AgoraDirectCdnStreamingEventDelegate.h>
#import <AgoraRtcKit/AgoraMediaFilterEventDelegate.h>
#import <AgoraRtcKit/AgoraSpatialAudioKit.h>
#import <AgoraRtcKit/AgoraMusicContentCenter.h>
#import <AgoraRtcKit/AgoraRtcMediaPlayerCacheManagerProtocol.h>

View File

@@ -0,0 +1,33 @@
//
// Copyright (c) 2018 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "AgoraConstants.h"
#import "AgoraObjects.h"
#import "AgoraRtcMediaPlayerProtocol.h"
#import "AgoraH265TranscoderProtocol.h"
/** Agora provides ensured quality of experience (QoE) for worldwide Internet-based voice and video communications through a virtual global network that is especially optimized for real-time web and mobile-to-mobile applications.
The AgoraRtcEngineKit class is the entry point of the Agora SDK that provides simple APIs for applications to easily start voice and video communication.
*/
@class AgoraRtcEngineKit;
@class AgoraMediaRecorder;
@protocol AgoraRtcMediaPlayerAudioFrameDelegate <NSObject>
/** Occurs when each time the player receives an audio frame.
After registering the audio frame observer, the callback occurs when each
time the player receives an audio frame, reporting the detailed
information of the audio frame.
@param playerKit AgoraRtcMediaPlayer
@param audioFrame The detailed information of the audio frame.
*/
- (void)AgoraRtcMediaPlayer:(id<AgoraRtcMediaPlayerProtocol> _Nonnull)playerKit
didReceiveAudioFrame:(AgoraAudioFrame* _Nonnull)audioFrame NS_SWIFT_NAME(AgoraRtcMediaPlayer(_:didReceiveAudioFrame:));
@end

View File

@@ -0,0 +1,99 @@
//
// Copyright (c) 2020 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@protocol AgoraRtcMediaPlayerCacheManagerProtocol <NSObject>
/**
* Get shared cacheManager instance.
* @return cacheManager instance.
*/
+ (instancetype)sharedInstance NS_SWIFT_NAME(sharedInstance());
/**
* Remove all media resource cache files.
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)removeAllCaches NS_SWIFT_NAME(removeAllCaches());
/**
* Remove the latest media resource cache file.
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)removeOldCache NS_SWIFT_NAME(removeOldCache());
/**
* Remove the cache file by uri, setting by MediaSource.
* @param uri URIidentify the uniqueness of the property, Set from `MeidaSource`
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)removeCacheByUri:(NSString *)uri NS_SWIFT_NAME(removeCache(byUri:));
/**
* Set cache file path that files will be saved to.
* @param cacheDir cacheDir path.
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)setCacheDir:(NSString *)cacheDir NS_SWIFT_NAME(setCacheDir(_:));
/**
* Set the maximum number of cached files.
* @param count maximum number of cached files.
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)setMaxCacheFileCount:(NSInteger)count NS_SWIFT_NAME(setMaxCacheFileCount(_:));
/**
* Set the total size of the largest cache file.
* @param cacheSize total size of the largest cache file.
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)setMaxCacheFileSize:(NSInteger)cacheSize NS_SWIFT_NAME(setMaxCacheFileSize(_:));
/**
* Set whether the player will clean up the cache in the order of resource usage.
* @param enable enable the player to automatically clear the cache.
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)enableAutoRemoveCache:(BOOL)enable NS_SWIFT_NAME(enableAutoRemoveCache(_:));
/**
* Get the cache directory you have set.
* @return cacheDir
*/
- (NSString *)cacheDir NS_SWIFT_NAME(cacheDir());
/**
* Get the maximum number of cached files.
* @return
* > 0: file count.
* - < 0: Failure.
*/
- (NSInteger)maxCacheFileCount NS_SWIFT_NAME(maxCacheFileCount());
/**
* Get the total size of the largest cache file
* @return
* > 0: file size.
* - < 0: Failure.
*/
- (NSInteger)maxCacheFileSize NS_SWIFT_NAME(maxCacheFileSize());
/**
* Get the number of all cache files.
* @return
* > 0: file count.
* - < 0: Failure.
*/
- (NSInteger)cacheFileCount NS_SWIFT_NAME(cacheFileCount());
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,127 @@
//
// Copyright (c) 2018 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "AgoraConstants.h"
#import "AgoraObjects.h"
@protocol AgoraRtcMediaPlayerProtocol;
@protocol AgoraRtcMediaPlayerDelegate <NSObject>
@optional
/** Reports the playback state change.
@param playerKit AgoraRtcMediaPlayer
@param state The new playback state after change. See AgoraMediaPlayerState.
@param reason The player's error code. See AgoraMediaPlayerReason.
*/
- (void)AgoraRtcMediaPlayer:(id<AgoraRtcMediaPlayerProtocol> _Nonnull)playerKit
didChangedToState:(AgoraMediaPlayerState)state
reason:(AgoraMediaPlayerReason)reason NS_SWIFT_NAME(AgoraRtcMediaPlayer(_:didChangedTo:reason:));
/** Reports current playback progress.
The callback occurs once every one second during the playback and reports
current playback progress.
@param playerKit AgoraMediaPlayer
@param positionMs Current playback progress (ms).
@param timestampMs The NTP timestamp (ms) when the position is sent.
*/
- (void)AgoraRtcMediaPlayer:(id<AgoraRtcMediaPlayerProtocol> _Nonnull)playerKit
didChangedToPosition:(NSInteger)positionMs
atTimestamp:(NSTimeInterval)timestampMs NS_SWIFT_NAME(AgoraRtcMediaPlayer(_:didChangedTo:atTimestamp:));
/** Reports the result of the seek operation.
@param playerKit AgoraRtcMediaPlayer
@param eventCode AgoraMediaPlayerEvent
@param elapsedTime The playback elapsed time.
@param message NSString
*/
- (void)AgoraRtcMediaPlayer:(id<AgoraRtcMediaPlayerProtocol> _Nonnull)playerKit
didOccurEvent:(AgoraMediaPlayerEvent)eventCode
elapsedTime:(NSInteger)elapsedTime
message:(NSString *_Nullable)message NS_SWIFT_NAME(AgoraRtcMediaPlayer(_:didOccur:elapsedTime:message:));
/** Reports the reception of the media metadata.
The callback occurs when the player receivers the media metadata and reports
the detailed information of the media metadata.
@param playerKit AgoraRtcMediaPlayer
@param data The detailed data of the media metadata.
@param length The length (byte) of the data.
*/
- (void)AgoraRtcMediaPlayer:(id<AgoraRtcMediaPlayerProtocol> _Nonnull)playerKit
didReceiveData:(NSString *_Nullable)data
length:(NSInteger)length NS_SWIFT_NAME(AgoraRtcMediaPlayer(_:didReceiveData:length:));
/**
* @brief Triggered when play buffer updated, once every 1 second
*
* @param playerKit AgoraRtcMediaPlayer
* @param playCachedBuffer NSInteger
*/
- (void)AgoraRtcMediaPlayer:(id<AgoraRtcMediaPlayerProtocol> _Nonnull)playerKit
didPlayBufferUpdated:(NSInteger)playCachedBuffer NS_SWIFT_NAME(AgoraRtcMediaPlayer(_:didPlayBufferUpdated:));
/**
* @brief Triggered when the player preloadSrc
*
* @param playerKit AgoraRtcMediaPlayer
* @param event AgoraMediaPlayerPreloadEvent
*/
- (void)AgoraRtcMediaPlayer:(id<AgoraRtcMediaPlayerProtocol> _Nonnull)playerKit
didPreloadEvent:(AgoraMediaPlayerPreloadEvent)event NS_SWIFT_NAME(AgoraRtcMediaPlayer(_:didPreloadEvent:));
/**
* @brief Reports current playback source bitrate changed.
*
* @param to Streaming media information after the change.
* @param from Streaming media information before the change.
*/
- (void)AgoraRtcMediaPlayer:(id<AgoraRtcMediaPlayerProtocol> _Nonnull)playerKit playerSrcInfoDidChange:(AgoraMediaPlayerSrcInfo *_Nonnull)to from:(AgoraMediaPlayerSrcInfo *_Nonnull)from NS_SWIFT_NAME(AgoraRtcMediaPlayer(_:playerSrcInfoDidChange:from:));
/**
* @brief Triggered when media player information updated.
*
* @param info Include information of media player.
*/
- (void)AgoraRtcMediaPlayer:(id<AgoraRtcMediaPlayerProtocol> _Nonnull)playerKit infoUpdated:(AgoraMediaPlayerUpdatedInfo *_Nonnull)info NS_SWIFT_NAME(AgoraRtcMediaPlayer(_:infoUpdated:));
/**
* @brief Triggered every 1 second, reports the statistics of the files being cached.
*
* @param stats Cached file statistics.
*/
- (void)AgoraRtcMediaPlayer:(id<AgoraRtcMediaPlayerProtocol> _Nonnull)playerKit cacheStats:(AgoraMediaPlayerCacheStatistics *_Nonnull)info NS_SWIFT_NAME(AgoraRtcMediaPlayer(_:cacheStats:));
/**
* @brief Triggered every 1 second, reports the statistics of the media stream being played.
*
* @param stats The statistics of the media stream.
*/
- (void)AgoraRtcMediaPlayer:(id<AgoraRtcMediaPlayerProtocol> _Nonnull)playerKit playbackStats:(AgoraMediaPlayerPlaybackStats *_Nonnull)info NS_SWIFT_NAME(AgoraRtcMediaPlayer(_:playbackStats:));
/**
* @brief AgoraCDN Token has expired and needs to be set up with renewAgoraCDNSrcToken(const char*
* src).
*/
- (void)onAgoraCDNTokenWillExpire NS_SWIFT_NAME(onAgoraCDNTokenWillExpire());
/**
* @brief Triggered when play volume updated, once every 200 millisecond
*
* @param volume volume of current player.
*/
- (void)AgoraRtcMediaPlayer:(id<AgoraRtcMediaPlayerProtocol> _Nonnull)playerKit
volumeIndicationDidReceive:(NSInteger)volume NS_SWIFT_NAME(AgoraRtcMediaPlayer(_:volumeIndicationDidReceive:));
@end

View File

@@ -0,0 +1,446 @@
//
// AgoraRtcMediaPlayerProtocol.h
// AgoraRtcMediaPlayerProtocol
//
// Copyright (c) 2020 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "AgoraObjects.h"
#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
typedef UIView View;
#elif TARGET_OS_MAC
#import <AppKit/AppKit.h>
typedef NSView View;
#endif
@protocol AgoraRtcAudioSpectrumDelegateocol;
@protocol AgoraRtcMediaPlayerAudioFrameDelegate;
@protocol AgoraRtcMediaPlayerVideoFrameDelegate;
@protocol AgoraAudioSpectrumDelegate;
NS_ASSUME_NONNULL_BEGIN
@protocol AgoraRtcMediaPlayerProtocol <NSObject>
/**
* Get unique media player id of the media player entity.
* @return
* - >= 0: The mediaPlayerId of this media player entity.
* - < 0: Failure.
*/
- (int)getMediaPlayerId NS_SWIFT_NAME(getMediaPlayerId());
/**
* Opens a media file with a specified URL.
* @param url The URL of the media file that you want to play.
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)open:(NSString *)url startPos:(NSInteger)startPos NS_SWIFT_NAME(open(_:startPos:));
/**
* Opens a media file with MediaSource
* @param source see `AgoraMediaSource`
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)openWithMediaSource:(AgoraMediaSource *)source NS_SWIFT_NAME(open(with:));
/**
* Open the Agora CDN media source.
* @param src The src of the media file that you want to play.
* @param startPos The playback position (ms).
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)openWithAgoraCDNSrc:(NSString *)src startPos:(NSInteger)startPos NS_SWIFT_NAME(open(withAgoraCDNSrc:startPos:));
/**
* Gets the number of Agora CDN lines.
* @return
* - > 0: number of CDN.
* - <= 0: Failure.
*/
- (int)getAgoraCDNLineCount NS_SWIFT_NAME(getAgoraCDNLineCount());
/**
* Switch Agora CDN lines.
* @param index Specific line.
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)switchAgoraCDNLineByIndex:(int)index NS_SWIFT_NAME(switchAgoraCDNLine(by:));
/**
* Gets the line of the current CDN.
* @return
* - >= 0: Specific line.
* - < 0: Failure.
*/
- (int)getCurrentAgoraCDNIndex NS_SWIFT_NAME(getCurrentAgoraCDNIndex());
/**
* Enable automatic CDN line switching.
* @param enable Whether enable.
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)enableAutoSwitchAgoraCDN:(BOOL)enable NS_SWIFT_NAME(enableAutoSwitchAgoraCDN(_:));
/**
* Update the CDN source token and timestamp.
* @param token token.
* @param ts ts.
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)renewAgoraCDNSrcToken:(NSString *)token ts:(NSInteger)ts NS_SWIFT_NAME(renewAgoraCDNSrcToken(_:ts:));
/**
* Switch the CDN source.
* @param src Specific line.
* @param syncPts Live streaming must be set to false.
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)switchAgoraCDNSrc:(NSString *)src syncPts:(BOOL)syncPts NS_SWIFT_NAME(switchAgoraCDNSrc(_:syncPts:));
/**
* Plays the media file.
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)play NS_SWIFT_NAME(play());
/**
* Pauses playing the media file.
*/
- (int)pause NS_SWIFT_NAME(pause());
/**
* Stops playing the current media file.
*/
- (int)stop NS_SWIFT_NAME(stop());
/**
* Resumes playing the media file.
*/
- (int)resume NS_SWIFT_NAME(resume());
/**
* Sets the current playback position of the media file.
* @param position The new playback position (ms).
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)seekToPosition:(NSInteger)position NS_SWIFT_NAME(seek(toPosition:));
/**
* Sets the pitch of the current media file.
* @param pitch Sets the pitch of the local music file by chromatic scale. The default value is 0,
* which means keeping the original pitch. The value ranges from -12 to 12, and the pitch value
* between consecutive values is a chromatic value. The greater the absolute value of this
* parameter, the higher or lower the pitch of the local music file.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)setAudioPitch:(NSInteger)pitch NS_SWIFT_NAME(setAudioPitch(_:));
/**
* Gets the duration of the media file.
*/
- (NSInteger)getDuration NS_SWIFT_NAME(getDuration());
/**
* Gets the current playback position of the media file.(ms).
*/
- (NSInteger)getPosition NS_SWIFT_NAME(getPosition());
/**
* Gets the number of the media streams in the media resource.
*/
- (NSInteger)getStreamCount NS_SWIFT_NAME(getStreamCount());
/** Gets the detailed information of the media stream.
@param index The index of the media stream.
@return * If the call succeeds, returns the detailed information of the media
stream. See AgoraMediaStreamInfo.
* If the call fails and returns nil.
*/
- (AgoraRtcMediaStreamInfo *_Nullable)getStreamByIndex:(int)index NS_SWIFT_NAME(getStreamBy(_:));
/**
* Sets whether to loop the media file for playback.
* @param loopCount the number of times looping the media file.
* - 0: Play the audio effect once.
* - 1: Play the audio effect twice.
* - -1: Play the audio effect in a loop indefinitely, until stopEffect() or stop() is called.
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)setLoopCount:(int)loopCount NS_SWIFT_NAME(setLoopCount(_:));
/**
* Change playback speed
* @param speed the enum of playback speed
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)setPlaybackSpeed:(int)speed NS_SWIFT_NAME(setPlaybackSpeed(_:));
/**
* Select playback audio track of the media file
* @param index the index of the audio track in media file
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)selectAudioTrack:(int)index NS_SWIFT_NAME(selectAudioTrack(_:));
/**
* Selects multi audio track of the media file for playback or publish to channel.
* @param playoutTrackIndex The index of the audio track in media file for local playback.
* @param publishTrackIndex The index of the audio track in the media file published to the remote.
*
* @note
* You can obtain the streamIndex of the audio track by calling getStreamInfo..
* If you want to use selectMultiAudioTrack, you need to open the media file with openWithMediaSource and set enableMultiAudioTrack to true.
*
* @return
* - 0: Success.
* - < 0: Failure. See {@link media::base::MEDIA_PLAYER_REASON MEDIA_PLAYER_REASON}.
* - -2: Invalid argument. Argument must be greater than or equal to zero.
* - -8: Invalid State.You must open the media file with openWithMediaSource and set enableMultiAudioTrack to true
*/
- (int)selectMultiAudioTrack:(NSInteger)playoutTrackIndex publishTrackIndex:(NSInteger)publishTrackIndex NS_SWIFT_NAME(selectMultiAudioTrack(_:publishTrackIndex:));
/**
* take screenshot while playing video
* @param filename the filename of screenshot file
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)takeScreenshot:(NSString *)filename NS_SWIFT_NAME(takeScreenshot(_:));
/**
* select internal subtitles in video
* @param index the index of the internal subtitles
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)selectInternalSubtitle:(int)index NS_SWIFT_NAME(selectInternalSubtitle(_:));
/**
* set an external subtitle for video
* @param url The URL of the subtitle file that you want to load.
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)setExternalSubtitle:(NSString *)url NS_SWIFT_NAME(setExternalSubtitle(_:));
/** Gets current playback state.
@return * The call succeeds and returns current playback state. See
AgoraMediaPlayerState.
* The call fails and returns nil.
*/
- (AgoraMediaPlayerState)getPlayerState NS_SWIFT_NAME(getPlayerState());
/**
* @brief Turn mute on or off
*
* @param isMute Whether the media source is mute.
* YES: Yes.
* NO: No.
* @return mute Whether to mute on
*/
- (int)mute:(BOOL)isMute NS_SWIFT_NAME(mute(_:));
/**
* @brief Get mute state
*
* @return mute Whether is mute on
*/
- (BOOL)getMute NS_SWIFT_NAME(getMute());
/**
* @brief Adjust playback volume
*
* @param volume The volume value to be adjusted
* The volume can be adjusted from 0 to 400:
* 0: mute;
* 100: original volume;
* 400: Up to 4 times the original volume (with built-in overflow protection).
* @return int < 0 on behalf of an error, the value corresponds to one of MEDIA_PLAYER_REASON
*/
- (int)adjustPlayoutVolume:(int)volume NS_SWIFT_NAME(adjustPlayoutVolume(_:));
/**
* @brief Get the current playback volume
*
* @return volume
*/
- (int)getPlayoutVolume NS_SWIFT_NAME(getPlayoutVolume());
/**
* @brief adjust publish signal volume
*/
- (int)adjustPublishSignalVolume:(int)volume NS_SWIFT_NAME(adjustPublishSignalVolume(_:));
/**
* @brief get publish signal volume
*/
- (int)getPublishSignalVolume NS_SWIFT_NAME(getPublishSignalVolume());
/**
* @brief Modify player option before opening file or url,
* @param [in] key
* the option key name
* @param [in] value
* the option value
* @return
* - 0: Success.
* - < 0: Failure. See AgoraMediaPlayerReason.
*/
- (int)setPlayerOption:(NSString *)key value:(NSInteger)value NS_SWIFT_NAME(setPlayerOption(_:value:));
/**
* @brief Modify player option before opening file or url,
* @param [in] key
* the option key name
* @param [in] value
* the option value
* @return
* - 0: Success.
* - < 0: Failure. See AgoraMediaPlayerReason.
*/
- (int)setPlayerOptionString:(NSString *)key value:(NSString *)value NS_SWIFT_NAME(setPlayerOptionString(_:value:));
/**
* @brief Set video rendering view
*/
- (int)setView:(View *_Nullable)view NS_SWIFT_NAME(setView(_:));
/**
* @brief Set video display mode
*
* @param mode Video display mode
* @return int < 0 on behalf of an error, the value corresponds to one of MEDIA_PLAYER_REASON
*/
- (int)setRenderMode:(AgoraMediaPlayerRenderMode)mode NS_SWIFT_NAME(setRenderMode(_:));
/**
* Get the current play src.
* @return
* - current play src of raw bytes.
*/
- (NSString *)getPlaySrc NS_SWIFT_NAME(getPlaySrc());
/**
* Switch the media source when open a media through "open" API
* @param src Specific src.
* @param syncPts Live streaming must be set to false.
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)switchSrc:(NSString *)src syncPts:(BOOL)syncPts NS_SWIFT_NAME(switchSrc(_:syncPts:));
/**
* Preload a media source
* @param src Specific src.
* @param startPos The starting position (ms) for playback. Default value is 0.
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)preloadSrc:(NSString *)src startPos:(int)startPos NS_SWIFT_NAME(preloadSrc(_:startPos:));
/**
* unload a media source
* @param src Specific src.
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)unloadSrc:(NSString *)src NS_SWIFT_NAME(unloadSrc(_:));
/**
* Play a pre-loaded media source
* @param src Specific src.
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)playPreloadedSrc:(NSString *)src NS_SWIFT_NAME(playPreloadedSrc(_:));
/** Set dual-mono output mode of the music file.
@param mode The audio dual mono mode. See AgoraAudioDualMonoMode.
@return
- 0: Success.
- < 0: Failure.
*/
- (int)setAudioDualMonoMode:(AgoraAudioDualMonoMode)mode NS_SWIFT_NAME(setAudioDualMonoMode(_:));
/**
* Set spatial audio params for the music file. It can be called after the media player
* was created.
*
* @params params See `AgoraSpatialAudioParams`. If it's
* not set, then the spatial audio will be disabled; or it will be enabled.
* @return
* - 0: Success.
* - < 0: Failure.
*/
- (int)setSpatialAudioParams:(AgoraSpatialAudioParams* _Nonnull)params NS_SWIFT_NAME(setSpatialAudioParams(_:));
#pragma mark Callback Audio PCM Frame
/**
* Registers & unregister the player audio observer
*
* @param delegate observer object, pass nil to unregister
* @return
* - YES: Success.
* - NO: Failure.
*/
- (BOOL)setAudioFrameDelegate:(id<AgoraRtcMediaPlayerAudioFrameDelegate> _Nullable)delegate NS_SWIFT_NAME(setAudioFrameDelegate(_:));
#pragma mark Callback Video Frame
/**
* Registers & unregister the player video observer
*
* @param delegate observer object, pass nil to unregister.
* @return
* - YES: Success.
* - NO: Failure.
*/
- (BOOL)setVideoFrameDelegate:(id<AgoraRtcMediaPlayerVideoFrameDelegate> _Nullable)delegate NS_SWIFT_NAME(setVideoFrameDelegate(_:));
- (int)registerMediaPlayerAudioSpectrumDelegate:(id<AgoraAudioSpectrumDelegate> _Nullable)delegate
intervalInMS:(NSUInteger)intervalInMS NS_SWIFT_NAME(registerMediaPlayerAudioSpectrumDelegate(_:intervalInMS:));
- (int)unregisterMediaPlayerAudioSpectrumDelegate:(id<AgoraAudioSpectrumDelegate> _Nullable)delegate NS_SWIFT_NAME(unregisterMediaPlayerAudioSpectrumDelegate(_:));
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,45 @@
//
// Copyright (c) 2018 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "AgoraRtcMediaPlayerProtocol.h"
@protocol AgoraRtcMediaPlayerProtocol;
@class AgoraOutputVideoFrame;
@protocol AgoraRtcMediaPlayerVideoFrameDelegate <NSObject>
@optional
/** Occurs when each time the player receives a video frame.
After registering the video frame observer, the callback occurs when each
time the player receives a video frame, reporting the detailed
information of the video frame.
@param playerKit AgoraRtcMediaPlayer
@param videoFrame The detailed information of the video frame.
*/
- (void)AgoraRtcMediaPlayer:(id<AgoraRtcMediaPlayerProtocol> _Nonnull)playerKit
didReceiveVideoFrame:(AgoraOutputVideoFrame * _Nonnull)videoFrame NS_SWIFT_NAME(AgoraRtcMediaPlayer(_:didReceiveVideoFrame:));
/** Occurs when each time the player receives a video frame.
After registering the video frame observer, the callback occurs when each
time the player receives a video frame, reporting the detailed
information of the CVPixelBufferRef.
@param playerKit AgoraRtcMediaPlayer
@param pixelBuffer The detailed information of the CVPixelBufferRef. Format define by AgoraRtcMediaPlayerGetVideoPixelFormat.
*/
- (void)AgoraRtcMediaPlayer:(id<AgoraRtcMediaPlayerProtocol> _Nonnull)playerKit
didReceivePixelBuffer:(CVPixelBufferRef _Nonnull)pixelBuffer NS_SWIFT_NAME(AgoraRtcMediaPlayer(_:didReceivePixelBuffer:));
/**
* Occurs each time needs to get preference video frame type.
* @return AgoraVideoFormat.
*/
- (AgoraVideoFormat)AgoraRtcMediaPlayerGetVideoPixelFormat NS_SWIFT_NAME(AgoraRtcMediaPlayerGetVideoPixelFormat());
@end

View File

@@ -0,0 +1,200 @@
/**
*
* Agora Real Time Engagement
* Copyright (c) 2024 Agora IO. All rights reserved.
*
*/
#import <Foundation/Foundation.h>
@class AgoraRteError;
@class AgoraRteObserver;
/**
* The InitialConfig class is used to initialize the AgoraRte object.
* @since v4.4.0
* @technical preview
*/
__attribute__((visibility("default"))) @interface AgoraRteInitialConfig : NSObject
- (instancetype _Nonnull)init;
@end
/**
* AgoraRte configuration class. Used to configure the AgoraRte object.
* @since v4.4.0
*/
__attribute__((visibility("default"))) @interface AgoraRteConfig : NSObject
- (instancetype _Nonnull)init;
/**
* Set the App ID, used during engine initialization. This field needs to be set before calling [AgoraRte initMediaEngine:error:] to initialize the engine.
* If not set, the default value is an empty string.
* @since v4.4.0
* @param appId Your project's App ID
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidArgument: Indicates that the app_id parameter is empty.
* @return void
*/
- (void)setAppId:(NSString * _Nullable)appId error:(AgoraRteError * _Nullable)error;
/**
* Get the set App ID.
* @since v4.4.0
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* @return NSString Returns the set App ID value
*/
- (NSString* _Nullable)appId:(AgoraRteError * _Nullable)error;
- (void)setLogFolder:(NSString * _Nullable)logFolder error:(AgoraRteError * _Nullable)error;
- (NSString* _Nullable)logFolder:(AgoraRteError * _Nullable)error;
- (void)setLogFileSize:(size_t)logFileSize error:(AgoraRteError * _Nullable)error;
- (size_t)logFileSize:(AgoraRteError * _Nullable)error;
- (void)setAreaCode:(int32_t)areaCode error:(AgoraRteError * _Nullable)error;
- (int32_t)areaCode:(AgoraRteError * _Nullable)error;
- (void)setCloudProxy:(NSString * _Nullable)cloudProxy error:(AgoraRteError * _Nullable)error;
- (NSString * _Nullable)cloudProxy:(AgoraRteError * _Nullable)error;
/**
* Set JSON formatted parameters, usually used to set certain private parameters supported by AgoraRte.
* @since v4.4.0
* @param jsonParameter JSON formatted parameter set
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidArgument: Indicates that the jsonParameter parameter is empty.
* @return void
*/
- (void)setJsonParameter:(NSString * _Nullable)jsonParameter error:(AgoraRteError * _Nullable)error;
/**
* Get the currently configured private parameters of the Rte.
* @since v4.4.0
* @param error
* - AgoraRteOk: Success
* @return NSString The set JSON formatted parameter set
*/
- (NSString * _Nullable)jsonParameter:(AgoraRteError * _Nullable)error;
@end
/**
* The AgoraRte class, which is the basic interface of the Agora Real Time Engagement SDK.
* @since v4.4.0
*/
__attribute__((visibility("default"))) @interface AgoraRte : NSObject
/**
* Create an AgoraRte object from the rtc bridge. Used in scenarios where the rtc engine has already been initialized, which can save the operation of initializing the AgoraRte engine.
* @since v4.4.0
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidOperation: Indicates that the rtc engine instance has not been created or the rtc engine has not been initialized. Unable to bridge AgoraRte from rtc engine.
* @return AgoraRte object. If the AgoraRte object is invalid, subsequent operations on AgoraRte will return an error.
*/
+ (instancetype _Nonnull)getFromBridge:(AgoraRteError * _Nullable)error;
/**
* Construct an AgoraRte object.
* @since v4.4.0
* @param config AgoraRte object initialization configuration object.
*/
- (instancetype _Nonnull)initWithInitialConfig:(AgoraRteInitialConfig * _Nullable)config;
/**
* Initialize the engine.
* @since v4.4.0
* @param cb Asynchronous callback that returns the result of engine initialization.
* - @param err AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorDefault: Engine initialization failed, specific error reason can be obtained through [Error message].
* - AgoraRteErrorInvalidOperation: AgoraRte object created through GetFromBridge, initialization is not allowed.
*
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorDefault: Engine initialization failed, specific error description can be obtained through [Error message].
* - AgoraRteErrorInvalidOperation: The corresponding internal AgoraRte object has been destroyed or is invalid.
* @return BOOL Returns whether the asynchronous operation was successfully placed in the asynchronous operation queue, not whether the initialization action was successful.
* - YES: Asynchronous initialization action executed normally.
* - NO: Asynchronous initialization action did not execute normally.
*/
- (BOOL)initMediaEngine:(void (^ _Nullable)(AgoraRteError* _Nullable err) )cb error:(AgoraRteError * _Nullable)error;
/**
* Get the configuration of AgoraRte object.
* @since v4.4.0
* @param config The object used to receive AgoraRte configuration information.
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidOperation: The corresponding internal AgoraRte object has been destroyed or is invalid.
* - AgoraRteErrorInvalidArgument: The passed config object is null.
* @return BOOL Returns the result of getting the configuration.
* - YES: Successfully retrieved.
* - NO: Failed to retrieve.
*/
- (BOOL)getConfigs:(AgoraRteConfig *_Nonnull)config error:(AgoraRteError * _Nullable)error;
/**
* Configure the AgoraRte object.
* @since v4.4.0
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidOperation: The corresponding internal AgoraRte object has been destroyed or is invalid.
* - AgoraRteErrorInvalidArgument: The passed config object is null.
* @return BOOL Returns the result of setting the configuration.
* - YES: Successfully set.
* - NO: Failed to set.
*/
- (BOOL)setConfigs:(AgoraRteConfig * _Nonnull)config error:(AgoraRteError * _Nullable)error;
/**
* Register AgoraRte observer.
* @since v4.4.0
* @param observer The object that observes AgoraRte callback events.
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidOperation: The corresponding internal AgoraRte object has been destroyed or is invalid.
* - AgoraRteErrorInvalidArgument: The registered observer object is null.
* @return BOOL Returns the result of registering the observer.
* - YES: Registration is successful
* - NO: Registration failed
* @technical preview
*/
- (BOOL)registerObserver:(AgoraRteObserver * _Nonnull)observer error:(AgoraRteError * _Nullable)error;
/**
* Unregister AgoraRte observer.
* @since v4.4.0
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidOperation: The corresponding internal AgoraRte object has been destroyed or is invalid.
* - AgoraRteErrorInvalidArgument: The observer object to be unregistered is null.
* @return BOOL Returns the result of unregistering the observer.
* - YES: Unregistration is successful
* - NO: Unregistration failed
* @technical preview
*/
- (BOOL)unregisterObserver:(AgoraRteObserver * _Nullable)observer error:(AgoraRteError * _Nullable)error;
/**
* Destroy the AgoraRte object. The operation will release all resources used by the Rte object.
* @since v4.4.0
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidOperation: The corresponding internal AgoraRte object has already been destroyed or is invalid.
* @return BOOL Returns the result of destroying the AgoraRte object.
* - YES: Successfully destroyed
* - NO: Failed to destroy
*/
- (BOOL)destroy:(AgoraRteError * _Nullable)error;
@end

View File

@@ -0,0 +1,193 @@
/**
*
* Agora Real Time Engagement
* Copyright (c) 2024 Agora IO. All rights reserved.
*
*/
#import <Foundation/Foundation.h>
#import "AgoraRteEnumerates.h"
#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
typedef UIView AgoraRteView;
#elif TARGET_OS_MAC
#import <AppKit/AppKit.h>
typedef NSView AgoraRteView;
#endif
@class AgoraRteError;
@class AgoraRte;
/**
* The Rect class is used to manage the rect.
* @since v4.4.0
* @technical preview
*/
__attribute__((visibility("default"))) @interface AgoraRteRect : NSObject
- (instancetype _Nonnull)init;
- (void)setX:(int32_t)x;
- (int32_t)x;
- (void)setY:(int32_t)y;
- (int32_t)y;
- (void)setWidth:(int32_t)width;
- (int32_t)width;
- (void)setHeight:(int32_t)height;
- (int32_t)height;
@end
/**
* The ViewConfig class is used to manage the view config.
* @since v4.4.0
* @technical preview
*/
__attribute__((visibility("default"))) @interface AgoraRteViewConfig : NSObject
- (instancetype _Nonnull)init;
- (void)setCropArea:(AgoraRteRect* _Nullable)cropArea error:(AgoraRteError* _Nullable)error;
- (AgoraRteRect* _Nullable)cropArea:(AgoraRteError* _Nullable)error;
@end
/**
* The CanvasInitialConfig class is used to initialize the Canvas object.
* @since v4.4.0
* @technical preview
*/
__attribute__((visibility("default"))) @interface AgoraRteCanvasInitialConfig : NSObject
- (instancetype _Nonnull)init;
@end
/**
* The AgoraRteCanvasConfig class is used to configure the AgoraRteCanvas object.
* @since v4.4.0
*/
__attribute__((visibility("default"))) @interface AgoraRteCanvasConfig : NSObject
- (instancetype _Nonnull)init;
/**
* Set the video render mode.
* @since v4.4.0
* @param mode The render mode to set. Refer to AgoraRteVideoRenderMode type, default is AgoraRteVideoRenderModeHidden.
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidArgument: The mode parameter is set to an illegal value.
* @return void
*/
- (void)setVideoRenderMode:(AgoraRteVideoRenderMode)mode error:(AgoraRteError * _Nullable)error;
/**
* Get the render mode.
* @since v4.4.0
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* @return AgoraRteVideoRenderMode
*/
- (AgoraRteVideoRenderMode)videoRenderMode:(AgoraRteError * _Nullable)error;
/**
* Set the video mirror mode.
* @since v4.4.0
* @param mode The mirror mode to set. Refer to AgoraRteVideoMirrorMode type, default is AgoraRteVideoMirrorModeAuto.
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidArgument: The mode parameter is set to an illegal value.
* @return void
*/
- (void)setVideoMirrorMode:(AgoraRteVideoMirrorMode)mode error:(AgoraRteError* _Nullable)error;
/**
* Get the video mirror mode.
* @since v4.4.0
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* @return AgoraRteVideoMirrorMode
*/
- (AgoraRteVideoMirrorMode)videoMirrorMode:(AgoraRteError * _Nullable)error;
- (void)setCropArea:(AgoraRteRect* _Nonnull)cropArea error:(AgoraRteError * _Nullable)error;
- (AgoraRteRect* _Nonnull)cropArea:(AgoraRteError* _Nullable)error;
@end
/**
* AgoraRteCanvas interface, used to set the video rendering view.
* @since v4.4.0
*/
__attribute__((visibility("default"))) @interface AgoraRteCanvas : NSObject
/**
* Construct an AgoraRteCanvas object.
* @since v4.4.0
* @param rte AgoraRte object.
* @param config CanvasInitialConfig initialization configuration object. Currently, a null pointer can be passed.
*/
- (instancetype _Nonnull)initWithRte:(AgoraRte* _Nonnull)rte initialConfig:(AgoraRteCanvasInitialConfig * _Nullable)config;
/**
* Get the configuration of AgoraRteCanvas object.
* @since v4.4.0
* @param config CanvasConfig object
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidOperation: The corresponding internal Canvas object has been destroyed or is invalid.
* - AgoraRteErrorInvalidArgument: The passed config object is null.
* @return BOOL
* - YES: Successfully retrieved.
* - NO: Failed to retrieve.
*/
- (BOOL)getConfigs:(AgoraRteCanvasConfig* _Nonnull)config error:(AgoraRteError* _Nullable)error;
/**
* Configure the AgoraRteCanvas object.
* @since v4.4.0
* @param config CanvasConfig object
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidOperation: The corresponding internal Canvas object has been destroyed or is invalid.
* - AgoraRteErrorInvalidArgument: The passed config object is null.
* @return BOOL
* - YES: Successfully set the configuration.
* - NO: Failed to set the configuration.
*/
- (BOOL)setConfigs:(AgoraRteCanvasConfig* _Nonnull)config error:(AgoraRteError* _Nullable)error;
/**
* Add a rendering view. Currently, only one view is supported.
* @since v4.4.0
* @param view Pointer to the View object. On the iOS platform, you can assign an UIView object(NSView Object on mac) to a View type variable and pass it to the interface.
* @param config View-related configuration. Currently, nullptr can be passed.
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidOperation: The corresponding internal Canvas object has been destroyed or is invalid.
* - AgoraRteErrorInvalidArgument: The passed view is null.
* @return BOOL
* - YES: Successfully add the View.
* - NO: Failed to add the View.
*/
- (BOOL)addView:(AgoraRteView * _Nonnull)view config:(AgoraRteViewConfig* _Nullable)config error:(AgoraRteError* _Nullable)error;
/**
* Remove a rendering view.
* @since v4.4.0
* @param view Pointer to the View object.
* @param config View-related configuration. Currently, nullptr can be passed.
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidOperation: The corresponding internal Canvas object has been destroyed or is invalid.
* - AgoraRteErrorInvalidArgument: The passed view is null.
* @return BOOL
* - YES: Successfully removed the View.
* - NO: Failed to remove the View.
*/
- (BOOL)removeView:(AgoraRteView * _Nonnull)view config:(AgoraRteViewConfig* _Nullable)config error:(AgoraRteError* _Nullable)error;
@end

View File

@@ -0,0 +1,285 @@
#import <Foundation/Foundation.h>
/**
* Player states. When the player state changes, the state will be notified through the [AgoraRtePlayerObserver onStateChanged:newState:error] callback interface.
* @since v4.4.0
*/
typedef NS_ENUM(NSUInteger, AgoraRtePlayerState) {
/**
* 0: Idle state.
*/
AgoraRtePlayerStateIdle = 0,
/**
* 1: Opening state. This state is notified after calling [AgoraRtePlayer openWithUrl:startTime:cb].
*/
AgoraRtePlayerStateOpening = 1,
/**
* 2: Open completed state. This state is notified after successfully calling [AgoraRtePlayer openWithUrl:startTime:cb].
*/
AgoraRtePlayerStateOpenCompleted = 2,
/**
* 3: Playing state. This state is notified when the url source is playing.
*/
AgoraRtePlayerStatePlaying = 3,
/**
* 4: Paused state. This state is notified when playback is paused.
*/
AgoraRtePlayerStatePaused = 4,
/**
* Playback completed state. This state is notified when the url source playback completed
*/
AgoraRtePlayerStatePlaybackCompleted = 5,
/**
* 6: Stopped state. This state is entered after the user calls [AgoraRtePlayer stop:].
*/
AgoraRtePlayerStateStopped = 6,
/**
* 7: Failed state. This state is entered when an internal error occurs.
*/
AgoraRtePlayerStateFailed = 7
};
/**
* Player events. When an event occurs, it will be notified through the [AgoraRtePlayerObserver onEvent:] callback interface.
* @since v4.4.0
*/
typedef NS_ENUM(NSUInteger, AgoraRtePlayerEvent) {
/**
* 0: Start seeking to a specified position for playback.
*/
AgoraRtePlayerEventSeekBegin = 0,
/**
* 1: Seeking completes.
*/
AgoraRtePlayerEventSeekComplete = 1,
/**
* 2: An error occurs when seeking to a new playback position.
*/
AgoraRtePlayerEventSeekError = 2,
/**
* 3: The currently buffered data is not enough to support playback.
*/
AgoraRtePlayerEventBufferLow = 3,
/**
* 4: The currently buffered data is just enough to support playback.
*/
AgoraRtePlayerEventBufferRecover = 4,
/**
* 5: Audio or video playback starts freezing.
*/
AgoraRtePlayerEventFreezeStart = 5,
/**
* 6: The audio or video playback resumes without freezing.
*/
AgoraRtePlayerEventFreezeStop = 6,
/**
* 7: One loop playback completed.
*/
AgoraRtePlayerEventOneLoopPlaybackCompleted = 7,
/**
* 8: URL authentication will expire.
*/
AgoraRtePlayerEventAuthenticationWillExpire = 8,
/**
* 9: When the fallback option is enabled, ABR revert to the audio-only layer due to poor network.
*/
AgoraRtePlayerEventAbrFallbackToAudioOnlyLayer = 9,
/**
* 10: ABR recovers from audio-only layer to video layer when fallback option is enabled.
*/
AgoraRtePlayerEventAbrRecoverFromAudioOnlyLayer = 10,
/**
* 11: Start switching to a new URL.
*/
AgoraRtePlayerEventSwitchBegin = 11,
/**
* 12: Switching to a new URL completes.
*/
AgoraRtePlayerEventSwitchComplete = 12,
/**
* 13: An error occurs when switching to a new URL.
*/
AgoraRtePlayerEventSwitchError = 13,
/**
* 14: The first frame of the video is displayed.
*/
AgoraRtePlayerEventFirstDisplayed = 14,
/**
* 15: The number of cached files reaches the maximum.
*/
AgoraRtePlayerEventReachCacheFileMaxCount = 15,
/**
* 16: The size of the cached file reaches the maximum.
*/
AgoraRtePlayerEventReachCacheFileMaxSize = 16,
/**
* 17: Start trying to open a new URL.
*/
AgoraRtePlayerEventTryOpenStart = 17,
/**
* 18: Trying to open a new URL succeeds.
*/
AgoraRtePlayerEventTryOpenSucceed = 18,
/**
* 19: Trying to open a new URL fails.
*/
AgoraRtePlayerEventTryOpenFailed = 19,
/**
* 20: Audio track changed.
*/
AgoraRtePlayerEventAudioTrackChanged = 20
};
/**
* Render mode
* @since v4.4.0
*/
typedef NS_ENUM(NSUInteger, AgoraRteVideoRenderMode) {
/**
* 0: The hidden mode will fill the entire view. Parts of the image that exceed the view will be cropped.
*/
AgoraRteVideoRenderModeHidden = 0,
/**
* 1: The fit mode will render the entire image within the view.
*/
AgoraRteVideoRenderModeFit = 1
};
/**
* Mirror mode
* @since v4.4.0
*/
typedef NS_ENUM(NSUInteger, AgoraRteVideoMirrorMode) {
/**
* 0: The SDK decides the mirror mode.
*/
AgoraRteVideoMirrorModeAuto = 0,
/**
* 1: Enable mirror mode.
*/
AgoraRteVideoMirrorModeEnabled = 1,
/**
* 2: Disable mirror mode.
*/
AgoraRteVideoMirrorModeDisabled = 2
};
/**
* Metadata type
* @since v4.4.0
*/
typedef NS_ENUM(NSUInteger, AgoraRtePlayerMetadataType) {
/**
* SEI type
*/
AgoraRtePlayerMetadataTypeSei = 0,
};
/**
* Error codes
* @since v4.4.0
*/
typedef NS_ENUM(NSUInteger, AgoraRteErrorCode) {
/**
* 0: Success
*/
AgoraRteOk = 0,
/**
* 1: Default, not specifically categorized
*/
AgoraRteErrorDefault = 1,
/**
* 2: Invalid argument passed to API call
*/
AgoraRteErrorInvalidArgument = 2,
/**
* 3: Unsupported API operation
*/
AgoraRteErrorInvalidOperation = 3,
/**
* 4: Network error
*/
AgoraRteErrorNetworkError = 4,
/**
* 5: Authentication failed
*/
AgoraRteErrorAuthenticationFailed = 5,
/**
* 6: Stream not found
*/
AgoraRteErrorStreamNotFound = 6,
};
/**
* ABR subscription layer. This enumeration can be used to set the value of the abr_subscription_layer query parameter in the rte URL.
* It can also be used in the [AgoraRtePlayerConfig setAbrSubscriptionLayer:error:] setting interface.
* @since v4.4.0
*/
typedef NS_ENUM(NSUInteger, AgoraRteAbrSubscriptionLayer) {
/**
* 0: High-quality video stream, this layer has the highest resolution and bitrate.
*/
AgoraRteAbrSubscriptionHigh = 0,
/**
* 1: Low-quality video stream, this layer has the lowest resolution and bitrate.
*/
AgoraRteAbrSubscriptionLow = 1,
/**
* 2: Layer1 video stream, this layer has lower resolution and bitrate than that of the high-quality video stream.
*/
AgoraRteAbrSubscriptionLayer1 = 2,
/**
* 3: Layer2 video stream, this layer has lower resolution and bitrate than layer1.
*/
AgoraRteAbrSubscriptionLayer2 = 3,
/**
* 4: Layer3 video stream, this layer has lower resolution and bitrate than layer2.
*/
AgoraRteAbrSubscriptionLayer3 = 4,
/**
* 5: Layer4 video stream, this layer has lower resolution and bitrate than layer3.
*/
AgoraRteAbrSubscriptionLayer4 = 5,
/**
* 6: Layer5 video stream, this layer has lower resolution and bitrate than layer4.
*/
AgoraRteAbrSubscriptionLayer5 = 6,
/**
* 7: Layer6 video stream, this layer has lower resolution and bitrate than layer5.
*/
AgoraRteAbrSubscriptionLayer6 = 7,
};
/**
* ABR fallback layer. This enumeration can be used to set the value of the abr_fallback_layer query parameter in the rte URL.
* It can also be used in the [AgoraRtePlayerConfig setAbrFallbackLayer:error:] setting interface.
* @since v4.4.0
*/
typedef NS_ENUM(NSUInteger, AgoraRteAbrFallbackLayer) {
/**
* 0: When the network quality is poor, it will not revert to a lower resolution stream.
* It may still revert to scalable video coding but will maintain the high-quality video resolution.
*/
AgoraRteAbrFallbackDisabled = 0,
/**
* 1: (Default) In a poor network environment, the receiver's SDK will receive the kRteAbrSubscriptionLow layer video stream.
*/
AgoraRteAbrFallbackLow = 1,
/**
* 2: In a poor network environment, the SDK may first receive the kRteAbrSubscriptionLow layer, and if the relevant layer exists,
* it will revert to kRteAbrSubscriptionLayer1 to kRteAbrSubscriptionLayer6. If the network environment is too poor to play video, the SDK will only receive audio.
*/
AgoraRteAbrFallbackAudioOnly = 2,
/**
* 3~8: If the receiving end SDK sets the fallback option, when the network quality deteriorates and the relevant layer exists,
* it will receive one of the layers from kRteAbrSubscriptionLayer1 to kRteAbrSubscriptionLayer6. The lower boundary of the fallback depends on the set fallback option.
*/
AgoraRteAbrFallbackLayer1 = 3,
AgoraRteAbrFallbackLayer2 = 4,
AgoraRteAbrFallbackLayer3 = 5,
AgoraRteAbrFallbackLayer4 = 6,
AgoraRteAbrFallbackLayer5 = 7,
AgoraRteAbrFallbackLayer6 = 8,
};

View File

@@ -0,0 +1,37 @@
/**
*
* Agora Real Time Engagement
* Copyright (c) 2024 Agora IO. All rights reserved.
*
*/
#import <Foundation/Foundation.h>
#import "AgoraRteEnumerates.h"
/**
* AgoraRteError class. Used to record the execution result of an interface call.
* @since v4.4.0
* @technical preview
*/
__attribute__((visibility("default"))) @interface AgoraRteError : NSObject
- (instancetype _Nonnull)init;
- (void)setErrorWithCode:(AgoraRteErrorCode)code message:(NSString * _Nullable)message;
/**
* This interface is used to get the specific error code.
* @since v4.4.0
* @return AgoraRteErrorCode Error code, Refer to the AgoraRteErrorCode type for details.
*/
- (AgoraRteErrorCode)code;
/**
* This interface is used to get the specific error description.
* @since v4.4.0
* @return NSString Error description.
*/
- (NSString * _Nullable)message;
@end

View File

@@ -0,0 +1,16 @@
//
// AgoraRteKit.h
// AgoraRteKit
//
// Copyright (c) 2018 Agora. All rights reserved.
//
#import <AgoraRtcKit/AgoraRte.h>
#import <AgoraRtcKit/AgoraRteCanvas.h>
#import <AgoraRtcKit/AgoraRteEnumerates.h>
#import <AgoraRtcKit/AgoraRteError.h>
#import <AgoraRtcKit/AgoraRteObserver.h>
#import <AgoraRtcKit/AgoraRtePlayer.h>
#import <AgoraRtcKit/AgoraRtePlayerObserver.h>
#import <AgoraRtcKit/AgoraRtePlayerCustomSourceProvider.h>
#import <AgoraRtcKit/AgoraRteStream.h>

View File

@@ -0,0 +1,20 @@
/**
*
* Agora Real Time Engagement
* Copyright (c) 2024 Agora IO. All rights reserved.
*
*/
#import <Foundation/Foundation.h>
/**
* The Observer class is used to manage the observer.
* @since v4.4.0
* @technical preview
*/
__attribute__((visibility("default"))) @interface AgoraRteObserver : NSObject
- (instancetype _Nonnull)init;
@end

View File

@@ -0,0 +1,619 @@
/**
*
* Agora Real Time Engagement
* Copyright (c) 2024 Agora IO. All rights reserved.
*
*/
#import <Foundation/Foundation.h>
#import "AgoraRteEnumerates.h"
@class AgoraRteError;
@class AgoraRte;
@class AgoraRtePlayerCustomSourceProvider;
@class AgoraRteStream;
@class AgoraRteCanvas;
@class AgoraRtePlayerObserver;
/**
* The PlayerInitialConfig class is used to initialize the Player object.
* @since v4.4.0
* @technical preview
*/
__attribute__((visibility("default"))) @interface AgoraRtePlayerInitialConfig : NSObject
-(instancetype _Nonnull)init;
@end
/**
* Player configuration class
* @since v4.4.0
*/
__attribute__((visibility("default"))) @interface AgoraRtePlayerConfig : NSObject
-(instancetype _Nonnull)init;
/**
* Whether to automatically play after a successful call to [AgoraRtePlayer openWithUrl:startTime:cb:].
* If not set, the default value is YES.
* @since v4.4.0
* @param autoPlay
* - YES: Automatically start streaming and playing after a successful opening.
* - NO: After a successful open with [AgoraRtePlayer openWithUrl:startTime:cb:], you need to actively call [AgoraRtePlayer play:] to play the audio and video stream.
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* @return void
*/
- (void)setAutoPlay:(BOOL)autoPlay error:(AgoraRteError * _Nullable)error;
/**
* Get the auto-play setting
* @since v4.4.0
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* @return BOOL
*/
- (BOOL)autoPlay:(AgoraRteError * _Nullable)error;
/**
* Set the playback speed parameter.
* @since v4.5.1
* @note You can call this method after calling [AgoraRtePlayer openWithUrl:startTime:cb:].
* @param speed The playback speed. The value range is [50,400].
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidArgument: The speed parameter is set to an illegal value.
*/
- (void)setPlaybackSpeed:(int32_t)speed error:(AgoraRteError * _Nullable)error;
/**
* Get the playback speed parameter.
* @since v4.5.1
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* @return int32_t The value of playback speed.
*/
- (int32_t)playbackSpeed:(AgoraRteError * _Nullable)error;
- (void)setPlayoutAudioTrackIdx:(int)idx error:(AgoraRteError * _Nullable)error;
- (int)playoutAudioTrackIdx:(AgoraRteError * _Nullable)error;
- (void)setPublishAudioTrackIdx:(int)idx error:(AgoraRteError * _Nullable)error;
- (int)publishAudioTrackIdx:(AgoraRteError * _Nullable)error;
- (void)setAudioTrackIdx:(int)idx error:(AgoraRteError * _Nullable)error;
- (int)audioTrackIdx:(AgoraRteError * _Nullable)error;
- (void)setSubtitleTrackIdx:(int)idx error:(AgoraRteError * _Nullable)error;
- (int)subtitleTrackIdx:(AgoraRteError * _Nullable)error;
- (void)setExternalSubtitleTrackIdx:(int)idx error:(AgoraRteError * _Nullable)error;
- (int)externalSubtitleTrackIdx:(AgoraRteError * _Nullable)error;
- (void)setAudioPitch:(int32_t)pitch error:(AgoraRteError * _Nullable)error;
- (int32_t)audioPitch:(AgoraRteError * _Nullable)error;
/**
* Set the playout volume parameter.
* @since v4.5.1
* @param volume The volume value to be set. The value range is [0, 400].
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidArgument: The volume parameter is set to an illegal value.
* return void
*/
- (void)setPlayoutVolume:(int32_t)volume error:(AgoraRteError * _Nullable)error;
/**
* Get the playout volume parameter.
* @since v4.5.1
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* @return int32_t The volume value of the player.
*/
- (int32_t)playoutVolume:(AgoraRteError * _Nullable)error;
- (void)setAudioPlaybackDelay:(int32_t)delay error:(AgoraRteError * _Nullable)error;
- (int32_t)audioPlaybackDelay:(AgoraRteError * _Nullable)error;
- (void)setAudioDualMonoMode:(int)mode error:(AgoraRteError * _Nullable)error;
- (int)audioDualMonoMode:(AgoraRteError * _Nullable)error;
- (void)setPublishVolume:(int32_t)volume error:(AgoraRteError * _Nullable)error;
- (int32_t)publishVolume:(AgoraRteError * _Nullable)error;
/**
* Set the loop count parameter.
* @since v4.5.1
* @param count The number of times looping the media file.
* - 1: Play the media file once.
* - 2: Play the media file twice.
* - -1: Play the media file in a loop indefinitely, until stop() is called.
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidArgument: Indicates that the count parameter is set to an illegal value.
* @return void
*/
- (void)setLoopCount:(int32_t)count error:(AgoraRteError * _Nullable)error;
/**
* Get the loop count parameter.
* @since v4.5.1
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* @return int32_t The number of times looping the media file.
*/
- (int32_t)loopCount:(AgoraRteError * _Nullable)error;
/**
* Set player private parameters. This parameter setting can be done according to actual needs, referring to the suggestions of Agora SA.
* @since v4.4.0
* @param jsonParameter JSON formatted string
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidArgument: Indicates that the jsonParameter parameter is empty.
* @return void
*/
- (void)setJsonParameter:(NSString * _Nonnull)jsonParameter error:(AgoraRteError * _Nullable)error;
/**
* Get the currently configured private parameters of the AgoraRtePlayer.
* @since v4.4.0
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* @return NSString
*/
- (NSString * _Nullable)jsonParameter:(AgoraRteError * _Nullable)error;
/**
* Set the ABR subscription layer.
* If ABR is not enabled, the audience can only switch the high and low video stream in the origin channel. After enabling it, the audience can switch any layer in the abr channel.
* @since v4.4.0
* @param layer The layer to subscribe to. Refer to the AgoraRteAbrSubscriptionLayer enumeration values for details.
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidArgument: An illegal AgoraRteAbrSubscriptionLayer value was set.
* @return void
*/
- (void)setAbrSubscriptionLayer:(AgoraRteAbrSubscriptionLayer)layer error:(AgoraRteError * _Nullable)error;
/**
* Get the ABR subscription layer.
* @since v4.4.0
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* @return AgoraRteAbrSubscriptionLayer The currently set subscription layer.
*/
- (AgoraRteAbrSubscriptionLayer)abrSubscriptionLayer:(AgoraRteError * _Nullable)error;
/**
* Set the ABR fallback layer option.
* If ABR is not enabled, after calling this method, the audience can only set AgoraRteAbrFallbackDisabled ~ AgoraRteAbrFallbackAudioOnly in the original channel.
* After enabling it, the audience can switch all values of AbrFallbackLayer in the abr channel.
* @since v4.4.0
* @param layer The ABR fallback option to set. Refer to the AgoraRteAbrFallbackLayer enumeration values for details.
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidArgument: An illegal AgoraRteAbrFallbackLayer value was set. Check the value of the passed layer parameter.
* @return void
*/
- (void)setAbrFallbackLayer:(AgoraRteAbrFallbackLayer)layer error:(AgoraRteError * _Nullable)error;
/**
* Get the ABR fallback layer option.
* @since v4.4.0
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* @return AgoraRteAbrFallbackLayer The currently set ABR fallback option.
*/
- (AgoraRteAbrFallbackLayer)abrFallbackLayer:(AgoraRteError * _Nullable)error;
@end
/**
* Player statistics. Can be actively obtained through the [AgoraRtePlayer getStats:] interface.
* @since v4.4.0
*/
__attribute__((visibility("default"))) @interface AgoraRtePlayerStats : NSObject
- (instancetype _Nonnull)init;
/**
* Decoding frame rate
*/
- (int)videoDecodeFrameRate;
/**
* Rendering frame rate
*/
- (int)videoRenderFrameRate;
/**
* Video bitrate
*/
- (int)videoBitrate;
/**
* Audio bitrate
*/
- (int)audioBitrate;
@end
/**
* Player information.
* When playerInfo changes, it will be notified through the [AgoraRtePlayerObserver onPlayerInfoUpdated:] callback interface. It can also be actively obtained through the [AgoraRtePlayer getInfo:error] interface.
* @since v4.4.0
*/
__attribute__((visibility("default"))) @interface AgoraRtePlayerInfo : NSObject
- (instancetype _Nonnull)init;
/**
* Current player state
*/
- (int)state;
/**
* @brief Get the duration time of the current media source.
* @since v4.5.1
* @note This is valid when playing local media files or on-demand streams.
* @return The duration time of the current media source, in milliseconds.
*/
- (long)duration;
/**
* Stream count. This field is only valid when opening a non-RTE URL.
*/
- (int)streamCount;
/**
* Whether there is an audio stream. Indicates whether the url source contains the audio stream.
* - YES: The url source contains the audio stream.
* - NO: The url source does not contain the audio stream.
*/
- (BOOL)hasAudio;
/**
* Whether there is a video stream. Indicates whether the url source contains the video stream.
* - YES: The url source contains the video stream.
* - NO: The url source does not contain the video stream.
*/
- (BOOL)hasVideo;
/**
* @brief Whether player stops receiving the audio stream.
* @since v4.4.0
* @details Indicates whether the player stops receiving the audio stream.
* @return bool Whether player stops receiving the audio stream.
* - YES: Stop receiving the audio stream.
* - NO: Continue receiving the audio stream.
*/
- (BOOL)isAudioMuted;
/**
* @brief Whether player stops receiving the video stream.
* @since v4.4.0
* @details Indicates whether the player stops receiving the video stream.
* @return bool Whether player stops receiving the video stream.
* - YES: Stop receiving the video stream.
* - NO: Continue receiving the video stream.
*/
- (BOOL)isVideoMuted;
/**
* @brief Get the video resolution height.
* @since v4.5.1
* @return The video resolution height, in pixels.
*/
- (int)videoHeight;
/**
* @brief Get the video resolution width.
* @since v4.5.1
* @return The video resolution width, in pixels.
*/
- (int)videoWidth;
/**
* The currently subscribed video layer. This field is only valid when you open an RTE URL.
*/
- (AgoraRteAbrSubscriptionLayer)abrSubscriptionLayer;
/**
* @brief Get the audio sample rate.
* @since v4.5.1
* @return The audio sample rate, in Hz.
*/
- (int)audioSampleRate;
/**
* Number of audio channels
*/
- (int)audioChannels;
/**
* @brief Get the audio bits per sample.
* @since v4.5.1
* @note This field is only valid when opening a non-RTE URL.
* @return The audio bits per sample, in bits.
*/
- (int)audioBitsPerSample;
/**
* The URL being played.
*/
- (NSString * _Nullable)currentUrl;
@end
/*
* Player class, can be used to play URL resources.
* @since v4.4.0
*/
__attribute__((visibility("default"))) @interface AgoraRtePlayer : NSObject
/**
* Preload URL, only valid for rte type URLs. This interface can speed up the [AgoraRtePlayer openWithUrl:startTime:cb] operation. Up to 20 URLs can be preloaded.
* If the limit is exceeded, new preloads will replace old ones.
* @since v4.4.0
* @param url rte type URL
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidArgument: The passed URL is empty or has an invalid format.
* @return BOOL Whether the preload operation was successful.
* - YES: Successfully preload the Rte URL.
* - NO: Failed to preload the Rte URL.
*/
+ (BOOL)preloadWithUrl:(NSString * _Nonnull)url error:(AgoraRteError * _Nullable)error;
/**
* Construct an AgoraRtePlayer object.
* @since v4.4.0
* @param rte AgoraRte object.
* @param config AgoraRtePlayerInitialConfig initialization configuration object. Currently, a null pointer can be passed.
*/
- (instancetype _Nonnull)initWithRte:(AgoraRte * _Nonnull)rte initialConfig:(AgoraRtePlayerInitialConfig * _Nullable)config;
/**
* Open URL resource. Currently, the rte URLs and cdn URLs and files are supported.
* This interface can also be used to refresh the token of an already opened RTE URL.
* For RTE URL format definition and token refresh method description, refer to the doc:
* https://doc.shengwang.cn/doc/rtc/android/best-practice/playing-url
* @since v4.4.0
* @param url The URL resource to open
* @param startTime Set the starting position for playback, in ms.
* @param cb Asynchronous callback to notify the result of the open operation. If an error occurs during open, it will enter the AgoraRtePlayerStateFailed state.
* You need to call the stop method before calling [AgoraRtePlayer openWithUrl:startTime:cb] again.
* @param err Possible ErrorCode returns. At this time, the new_state value corresponds to AgoraRtePlayerStateFailed.
* - AgoraRteOk: Success
* - AgoraRteErrorDefault: For specific reasons, see Error.message, including the following situations:
* - Failed to connect to the channel
* - AgoraRteErrorInvalidArgument:
* - Invalid appid
* - Invalid channelid
* - Invalid uid
* - AgoraRteErrorAuthenticationFailed:
* - Invalid token
* - Token expired
* - AgoraRteErrorInvalidOperation:
* - Engine not initialized
* @return void
*/
- (void)openWithUrl:(NSString * _Nonnull)url startTime:(uint64_t)startTime cb:(void (^_Nullable)(AgoraRteError* _Nullable err))cb;
- (void)openWithCustomSourceProvider:(AgoraRtePlayerCustomSourceProvider * _Nonnull)provider startTime:(uint64_t)startTime cb:(void (^_Nullable)(AgoraRteError* _Nullable err))cb;
- (void)openWithStream:(AgoraRteStream * _Nonnull)stream cb:(void (^_Nullable)(AgoraRteError* _Nullable err))cb;
/**
* Switch to a new URL. This interface can be used to switch to a new URL during playback.
*
* @note
* - This method is only valid when the player opens a non-RTE URL.
* - Call this method when the sdk returns the player state as AgoraRtePlayerStateOpenCompleted.
*
* @since v4.5.1
* @param url The new URL to switch to.
* @param syncPts Whether to synchronize the playback position (ms) after the switch operation:
* - YES: Synchronize the playback position.
* - NO: (Default)Do not synchronize the playback position.
* @param cb Callback to asynchronously notify the result of the switch operation.
* @param err Possible return values for ErrorCode:
* - AgoraRteOk: Success
* - AgoraRteErrorDefault: Failed to switch to the new URL.
* - AgoraRteErrorInvalidArgument: The passed URL is empty or has an invalid format.
* - AgoraRteErrorInvalidOperation:
* - The corresponding internal AgoraRtePlayer object has been destroyed or is invalid.
* - The opened URL is an RTE URL, switch to a new URL is not supported.
* @return void
*/
- (void)switchWithUrl:(NSString * _Nonnull)url syncPts:(BOOL)syncPts cb:(void (^_Nullable)(AgoraRteError* _Nullable err))cb;
/**
* Get player playback statistics.
* @since v4.4.0
* @param cb Asynchronous callback for statistical data.
* @param stats Statistical values.
* @param err AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* @return void
*/
- (void)getStats:(void (^_Nonnull)(AgoraRtePlayerStats* _Nonnull stats, AgoraRteError* _Nullable err))cb;
/**
* Set canvas. After the stream is successfully pulled, the video frame will be rendered on the set canvas.
* @since v4.4.0
* @param canvas The canvas object used to render video frames.
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidArgument: The canvas is null.
* - AgoraRteErrorInvalidOperation: The corresponding internal AgoraRtePlayer object has been destroyed or is invalid.
* @return BOOL The result of the setCanvas operation. If it fails, you can check the specific error through err.
* - YES: Successfully set the canvas.
* - NO: Failed to set the canvas.
*/
- (BOOL)setCanvas:(AgoraRteCanvas *_Nonnull)canvas error:(AgoraRteError * _Nullable)error;
/**
* Start stream playback.
* @since v4.4.0
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidOperation: The corresponding internal AgoraRtePlayer object has been destroyed or is invalid.
* @return BOOL The result of the play operation. If it fails, you can check the specific error through err.
* - YES: Successfully play.
* - NO: Failed to play.
*/
- (BOOL)play:(AgoraRteError * _Nullable)error;
/**
* Stop playback.
* @since v4.4.0
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidOperation: The corresponding internal AgoraRtePlayer object has been destroyed or is invalid.
* @return BOOL The result of the stop operation. If it fails, you can check the specific error through err.
* - YES: Successfully stop.
* - NO: Failed to stop.
*/
- (BOOL)stop:(AgoraRteError * _Nullable)error;
/**
* Pause playback.
* @since v4.4.0
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidOperation: The corresponding internal AgoraRtePlayer object has been destroyed or is invalid.
* @return BOOL The result of the pause operation. If it fails, you can check the specific error through err.
* - YES: Successfully pause.
* - NO: Failed to pause.
*/
- (BOOL)pause:(AgoraRteError * _Nullable)error;
/**
* Seek the playback position.
* @since v4.5.1
* @param newTime The new playback position to seek to.
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidOperation:
* - The corresponding internal AgoraRtePlayer object has been destroyed or is invalid.
* - The opened URL is an RTE URL, Seek is not supported.
* @return BOOL The result of the seek operation. If it fails, you can check the specific error through err.
* - YES: Successfully seek.
* - NO: Failed to seek
*/
- (BOOL)seek:(uint64_t)newTime error:(AgoraRteError * _Nullable)error;
/**
* Mute/unmute audio separately.
* @since v4.4.0
* @param mute Whether to mute.
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidOperation: The corresponding internal AgoraRtePlayer object has been destroyed or is invalid.
* @return BOOL The result of the muteAudio operation. If it fails, you can check the specific error through err.
* - YES: The mute operation was successful.
* - NO: The mute operation failed.
*/
- (BOOL)muteAudio:(BOOL)mute error:(AgoraRteError * _Nullable)error;
/**
* Mute/unmute video separately.
* @since v4.4.0
* @param mute Whether to mute.
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidOperation: The corresponding internal AgoraRtePlayer object has been destroyed or is invalid.
* @return BOOL The result of the muteVideo operation. If it fails, you can check the specific error through err.
* - YES: The mute operation was successful.
* - NO: The mute operation failedl.
*/
- (BOOL)muteVideo:(BOOL)mute error:(AgoraRteError * _Nullable)error;
/**
* Get the playback position.
* @since v4.5.1
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidOperation:
* - The corresponding internal AgoraRtePlayer object has been destroyed or is invalid.
* - The opened URL is an RTE URL, getPosition is not supported.
* @return uint64_t The current playback position, in milliseconds.
*/
- (uint64_t)getPosition:(AgoraRteError * _Nullable)error;
/**
* Get player information.
* @since v4.4.0
* @param info The object used to receive player information. After the interface call is successful, the player information will be copied to the info object.
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidOperation: The corresponding internal AgoraRtePlayer object has been destroyed or is invalid.
* - AgoraRteErrorInvalidArgument: The info object is null.
* @return BOOL The result of the getInfo operation. If it fails, you can check the specific error through err.
* - YES: Successfully get the player information.
* - NO: Failed to get the player information.
*/
- (BOOL)getInfo:(AgoraRtePlayerInfo * _Nonnull)info error:(AgoraRteError * _Nullable)error;
/**
* Get the configuration of AgoraRtePlayer object.
* @since v4.4.0
* @param config The object used to receive PlayerConfig information.
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidOperation: The corresponding internal AgoraRtePlayer object has been destroyed or is invalid.
* - AgoraRteErrorInvalidArgument: The config object is null.
* @return BOOL The result of the getConfigs operation. If it fails, you can check the specific error through err.
* - YES: Successfully retrieved.
* - NO: Failed to retrieve.
*/
- (BOOL)getConfigs:(AgoraRtePlayerConfig * _Nonnull)config error:(AgoraRteError * _Nullable)error;
/**
* Configure the AgoraRtePlayer object.
* @since v4.4.0
* @param config The object used to change the player configuration.
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidOperation: The corresponding internal AgoraRtePlayer object has been destroyed or is invalid.
* - AgoraRteErrorInvalidArgument: The config object is null.
* @return BOOL The result of the setConfigs operation. If it fails, you can check the specific error through err.
* - YES: Successfully set the configuration.
* - NO: Failed to set the configuration.
*/
- (BOOL)setConfigs:(AgoraRtePlayerConfig * _Nonnull)config error:(AgoraRteError * _Nullable)error;
/**
* Register player observer.
* @since v4.4.0
* @param observer The object used to receive player-related callbacks.
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidOperation: The corresponding internal AgoraRtePlayer object has been destroyed or is invalid.
* - AgoraRteErrorInvalidArgument: The observer object is null.
* @return BOOL The result of the registerObserver operation. If it fails, you can check the specific error through err.
* - YES: Registration is successful.
* - NO: Registration failed.
*/
- (BOOL)registerObserver:(AgoraRtePlayerObserver *_Nonnull)observer error:(AgoraRteError * _Nullable)error;
/**
* Unregister player observer.
* @since v4.4.0
* @param observer The object used to receive player-related callbacks.
* @param error AgoraRteError object may return the following AgoraRteErrorCode
* - AgoraRteOk: Success
* - AgoraRteErrorInvalidOperation: The corresponding internal AgoraRtePlayer object has been destroyed or is invalid.
* - AgoraRteErrorInvalidArgument: The observer object is null.
* @return BOOL The result of the unregisterObserver operation. If it fails, you can check the specific error through err.
* - YES: Unregistration is successful.
* - NO: Unregistration failed.
*/
- (BOOL)unregisterObserver:(AgoraRtePlayerObserver * _Nullable)observer error:(AgoraRteError * _Nullable)error;
@end

View File

@@ -0,0 +1,13 @@
#import <Foundation/Foundation.h>
/**
* The PlayerCustomSourceProvider class is used to manage the player custom source provider.
* @since v4.4.0
* @technical preview
*/
__attribute__((visibility("default"))) @interface AgoraRtePlayerCustomSourceProvider : NSObject
- (instancetype _Nonnull)init;
@end

View File

@@ -0,0 +1,97 @@
/**
*
* Agora Real Time Engagement
* Copyright (c) 2024 Agora IO. All rights reserved.
*
*/
#import <Foundation/Foundation.h>
#import "AgoraRtePlayer.h"
#import "AgoraRteEnumerates.h"
/**
* Player Observer, an interface for receiving player event callbacks.
* @since v4.4.0
*/
__attribute__((visibility("default"))) @interface AgoraRtePlayerObserver : NSObject
- (instancetype _Nonnull)init;
/**
* Player state callback. This function is called when the player state changes.
* @since v4.4.0
* @param oldState The previous state.
* @param newState The new state.
* @param error Possible ErrorCode returns. Only when the new_state value corresponds to AgoraRtePlayerStateFailed, you need to check the value of this parameter.
* - AgoraRteErrorDefault. For specific reasons, see Error.message, including the following situations:
* - Failed to connect to the channel.
* - AgoraRteErrorInvalidArgument.
* - Invalid appid.
* - Invalid channelid.
* - Invalid uid.
* - AgoraRteErrorAuthenticationFailed.
* - Invalid token.
* - Token expired.
* - AgoraRteErrorStreamNotFound. After entering the channel, no stream was received from the broadcaster for more than 10 seconds.
* @return void
*/
- (void)onStateChanged:(AgoraRtePlayerState)oldState newState:(AgoraRtePlayerState)newState error:(AgoraRteError * _Nullable)error;
/**
* Playback position change callback.
* @since v4.4.0
* @param currentTime Current playback progress (milisecond).
* @param utcTime Current playback progress (milisecond).
* @return void
*/
- (void)onPositionChanged:(uint64_t)currentTime utcTime:(uint64_t)utcTime;
/**
* Video resolution change callback.
* @since v4.4.0
* @param width The width of the video frame.
* @param height The height of the video frame.
* @return void
*/
- (void)onResolutionChanged:(int)width height:(int)height;
/**
* Event callback.
* @since v4.4.0
* @param event The event notified by the callback. Refer to AgoraRtePlayerEvent type. Currently, the following events can be handled accordingly:
* - AgoraRtePlayerEventFreezeStart: Indicates that stuttering has occurred or shows a loading animation.
* - AgoraRtePlayerEventFreezeStop: Indicates that stuttering has ended or stops the loading animation.
* - AgoraRtePlayerEventAuthenticationWillExpire: Regenerate the token, use the new token to construct the rte URL, and call Player::OpenWithUrl to refresh the token.
* - AgoraRtePlayerEventAbrFallbackToAudioOnlyLayer: Indicates that due to network reasons, it has fallen back to audio-only mode.
* - AgoraRtePlayerEventAbrRecoverFromAudioOnlyLayer: Indicates that it has recovered from audio-only mode to video mode.
* @return void
*/
- (void)onEvent:(AgoraRtePlayerEvent)event;
/**
* Metadata callback.
* @since v4.4.0
* @param type The type of metadata.
* @param data The metadata buffer.
* @return void
*/
- (void)onMetadata:(AgoraRtePlayerMetadataType)type data:(NSData * _Nonnull)data;
/**
* Player information update callback. This is called when fields in AgoraRtePlayerInfo are updated.
* @since v4.4.0
* @param info The current AgoraRtePlayerInfo information.
* @return void
*/
- (void)onPlayerInfoUpdated:(AgoraRtePlayerInfo * _Nonnull)info;
/**
* Update player current volume.
* @since v4.4.0
* @param volume The current volume of the player. The value range is [0, 255].
* @return void
*/
- (void)onAudioVolumeIndication:(int32_t)volume;
@end

View File

@@ -0,0 +1,12 @@
#import <Foundation/Foundation.h>
/**
* The Stream class is used to manage the stream.
* @since v4.4.0
* @technical preview
*/
__attribute__((visibility("default"))) @interface AgoraRteStream : NSObject
- (instancetype _Nonnull)init;
@end

View File

@@ -0,0 +1,101 @@
//
// Copyright (c) 2018 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "AgoraEnumerates.h"
#import "AgoraObjects.h"
#import <simd/simd.h>
@class AgoraRtcEngineKit;
@class AgoraRtcConnection;
__attribute__((visibility("default"))) @interface AgoraRemoteVoicePositionInfo : NSObject
@property(assign, nonatomic) simd_float3 position;
@property(assign, nonatomic) simd_float3 forward;
@end
__attribute__((visibility("default"))) @interface AgoraSpatialAudioZone : NSObject
//the zone id
@property(assign, nonatomic) NSInteger zoneSetId;
//zone center point
@property(nonatomic) simd_float3 position;
//forward direction
@property(nonatomic) simd_float3 forward;
//right direction
@property(nonatomic) simd_float3 right;
//up direction
@property(nonatomic) simd_float3 up;
//the forward side length of the zone
@property(assign, nonatomic) float forwardLength;
//tehe right side length of the zone
@property(assign, nonatomic) float rightLength;
//the up side length of the zone
@property(assign, nonatomic) float upLength;
//the audio attenuation of zone
@property(assign, nonatomic) float audioAttenuation;
@end
__attribute__((visibility("default"))) @interface AgoraLocalSpatialAudioConfig : NSObject
@property(assign, nonatomic) AgoraRtcEngineKit* _Nullable rtcEngine;
@end
NS_ASSUME_NONNULL_BEGIN
__attribute__((visibility("default"))) @interface AgoraSpatialAudioKitBase : NSObject
- (int)setMaxAudioRecvCount:(NSUInteger)maxCount NS_SWIFT_NAME(setMaxAudioRecvCount(_:));
- (int)setAudioRecvRange:(float)range NS_SWIFT_NAME(setAudioRecvRange(_:));
- (int)setDistanceUnit:(float)unit NS_SWIFT_NAME(setDistanceUnit(_:));
- (int)updatePlayerPositionInfo:(NSInteger)playerId positionInfo:(AgoraRemoteVoicePositionInfo* _Nonnull)positionInfo NS_SWIFT_NAME(updatePlayerPositionInfo(_:positionInfo:));
- (int)updateSelfPosition:(simd_float3)position axisForward:(simd_float3)axisForward axisRight:(simd_float3)axisRight axisUp:(simd_float3)axisUp NS_SWIFT_NAME(updateSelfPosition(_:axisForward:axisRight:axisUp:));
- (int)updateSelfTransform:(simd_float4x4)transform NS_SWIFT_NAME(updateSelfTransform(_:));
- (int)muteLocalAudioStream:(BOOL)mute NS_SWIFT_NAME(muteLocalAudioStream(_:));
- (int)muteAllRemoteAudioStreams:(BOOL)mute NS_SWIFT_NAME(muteAllRemoteAudioStreams(_:));
- (int)setZones:(NSArray<AgoraSpatialAudioZone*> * _Nullable)zones NS_SWIFT_NAME(setZones(_:));
- (int)setPlayerAttenuation:(double)attenuation playerId:(NSUInteger)playerId forceSet:(BOOL)forceSet NS_SWIFT_NAME(setPlayerAttenuation(_:playerId:forceSet:));
- (int)muteRemoteAudioStream:(NSUInteger)uid mute:(BOOL)mute NS_SWIFT_NAME(muteRemoteAudioStream(_:mute:));
- (int)clearRemotePositions NS_SWIFT_NAME(clearRemotePositions());
@end
__attribute__((visibility("default"))) @interface AgoraLocalSpatialAudioKit : AgoraSpatialAudioKitBase
+ (instancetype _Nonnull)sharedLocalSpatialAudioWithConfig:(AgoraLocalSpatialAudioConfig*)config NS_SWIFT_NAME(sharedLocalSpatialAudio(with:));
+ (void)destroy NS_SWIFT_NAME(destroy());
- (int)updateRemotePosition:(NSUInteger)uid positionInfo:(AgoraRemoteVoicePositionInfo*)posInfo NS_SWIFT_NAME(updateRemotePosition(_:positionInfo:));
- (int)updateRemotePositionEx:(NSUInteger)uid positionInfo:(AgoraRemoteVoicePositionInfo*)posInfo connection:(AgoraRtcConnection *)connection NS_SWIFT_NAME(updateRemotePositionEx(_:positionInfo:connection:));
- (int)removeRemotePosition:(NSUInteger)uid NS_SWIFT_NAME(removeRemotePosition(_:));
- (int)removeRemotePositionEx:(NSUInteger)uid connection:(AgoraRtcConnection *)connection NS_SWIFT_NAME(removeRemotePositionEx(_:connection:));
- (int)clearRemotePositionsEx:(AgoraRtcConnection *)connection NS_SWIFT_NAME(clearRemotePositionsEx(_:));
- (int)setRemoteAudioAttenuation:(double)attenuation uid:(NSUInteger)uid forceSet:(BOOL)forceSet NS_SWIFT_NAME(setRemoteAudioAttenuation(_:uid:forceSet:));
- (int)updateSelfPositionEx:(simd_float3)position
axisForward:(simd_float3)axisForward
axisRight:(simd_float3)axisRight
axisUp:(simd_float3)axisUp
connection:(AgoraRtcConnection *)connection NS_SWIFT_NAME(updateSelfPositionEx(_:axisForward:axisRight:axisUp:connection:));
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,159 @@
//
// AgoraRtcEngineKit.h
// AgoraRtcEngineKit
//
// Copyright (c) 2018 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "AgoraEnumerates.h"
@class AgoraOutputVideoFrame;
@protocol AgoraVideoFrameDelegate <NSObject>
@optional
/**
* Occurs each time the SDK receives a video frame captured by the local camera.
* Notes: If getVideoFrameProcessMode is read-only, use MUST implement this method
*
* After you successfully register the video frame observer, the SDK triggers this callback each time
* a video frame is received. In this callback, you can get the video data captured by the local
* camera. You can then pre-process the data according to your scenarios.
*
* After pre-processing, you can send the processed video data back to the SDK by setting the
* `videoFrame` parameter in this callback.
*
* @param videoFrame A pointer to the video frame: AgoraOutputVideoFrame
* @return Determines whether to ignore the current video frame if the pre-processing fails:
* - true: Do not ignore.
* - false: Ignore, in which case this method does not sent the current video frame to the SDK.
*/
- (BOOL)onCaptureVideoFrame:(AgoraOutputVideoFrame * _Nonnull)videoFrame sourceType:(AgoraVideoSourceType)sourceType;
/**
* Occurs each time the SDK receives a video frame before encoding.
*
* After you successfully register the video frame observer, the SDK triggers this callback each time
* when it receives a video frame. In this callback, you can get the video data before encoding. You can then
* process the data according to your particular scenarios.
*
* After processing, you can send the processed video data back to the SDK by setting the
* `videoFrame` parameter in this callback.
*
* The video data that this callback gets has been pre-processed, with its content cropped, rotated, and the image enhanced.
*
* @param videoFrame A pointer to the video frame: VideoFrame
* @return Determines whether to ignore the current video frame if the pre-processing fails:
* - true: Do not ignore.
* - false: Ignore, in which case this method does not sent the current video frame to the SDK.
*/
- (BOOL)onPreEncodeVideoFrame:(AgoraOutputVideoFrame * _Nonnull)videoFrame sourceType:(AgoraVideoSourceType)sourceType;
- (BOOL)onTranscodedVideoFrame:(AgoraOutputVideoFrame * _Nonnull)videoFrame NS_SWIFT_NAME(onTranscodedVideoFrame(_:));
/**
* Occurs each time the SDK receives a video frame sent by the remote user.
*
* After you successfully register the video frame observer, the SDK triggers this callback each time a
* video frame is received. In this callback, you can get the video data sent by the remote user. You
* can then post-process the data according to your scenarios.
*
* After post-processing, you can send the processed data back to the SDK by setting the `videoFrame`
* parameter in this callback.
*
* @param uid ID of the remote user who sends the current video frame.
* @param channelId Channel name.
* @param videoFrame A pointer to the video frame: AgoraOutputVideoFrame
* @return Determines whether to ignore the current video frame if the post-processing fails:
* - true: Do not ignore.
* - false: Ignore, in which case this method does not sent the current video frame to the SDK.
*/
- (BOOL)onRenderVideoFrame:(AgoraOutputVideoFrame * _Nonnull)videoFrame uid:(NSUInteger)uid channelId:(NSString * _Nonnull)channelId NS_SWIFT_NAME(onRenderVideoFrame(_:uid:channelId:));
/**
* Occurs each time the SDK receives a video frame decoded by the MediaPlayer.
*
* After you successfully register the video frame observer, the SDK triggers this callback each
* time a video frame is decoded. In this callback, you can get the video data decoded by the
* MediaPlayer. You can then pre-process the data according to your scenarios.
*
* After pre-processing, you can send the processed video data back to the SDK by setting the
* `videoFrame` parameter in this callback.
*
* @note
* - This callback will not be affected by the return values of \ref getVideoFrameProcessMode "getVideoFrameProcessMode", \ref getRotationApplied "getRotationApplied", \ref getMirrorApplied "getMirrorApplied", \ref getObservedFramePosition "getObservedFramePosition".
*
* @param videoFrame A pointer to the video frame: AgoraOutputVideoFrame
* @param mediaPlayerId of the mediaPlayer.
* @return Determines whether to ignore the current video frame if the pre-processing fails:
* - true: Do not ignore.
* - false: Ignore, in which case this method does not sent the current video frame to the SDK.
*/
- (BOOL)onMediaPlayerVideoFrame:(AgoraOutputVideoFrame * _Nonnull)videoFrame mediaPlayerId:(NSInteger)mediaPlayerId NS_SWIFT_NAME(onMediaPlayerVideoFrame(_:mediaPlayerId:));
/**
* Occurs each time needs to get rotation angle.
* @return rotation angle.
*/
- (BOOL)getRotationApplied NS_SWIFT_NAME(getRotationApplied());
/**
* Occurs each time needs to get whether mirror is applied or not.
* @return Determines whether to mirror.
* - true: need to mirror.
* - false: no mirror.
*/
- (BOOL)getMirrorApplied NS_SWIFT_NAME(getMirrorApplied());
/**
* Indicate the video frame mode of the observer.
* @return AgoraVideoFrameProcessMode
*/
- (AgoraVideoFrameProcessMode)getVideoFrameProcessMode NS_SWIFT_NAME(getVideoFrameProcessMode());
/**
* Occurs each time needs to get preference video frame type.
* @return AgoraVideoFormat.
*/
- (AgoraVideoFormat)getVideoFormatPreference NS_SWIFT_NAME(getVideoFormatPreference());
/**
* Sets the frame position for the video observer.
*
* After you successfully register the video observer, the SDK triggers this callback each time it receives
* a video frame. You can determine which position to observe by setting the return value. The SDK provides
* 3 positions for observer. Each position corresponds to a callback function:
*
* AgoraVideoFramePositionPostCapture(1 << 0): The position after capturing the video data, which corresponds to the onCaptureVideoFrame callback.
* AgoraVideoFramePositionPreRenderer(1 << 1): The position before receiving the remote video data, which corresponds to the onRenderVideoFrame callback.
* AgoraVideoFramePositionPreEncoder(1 << 2): The position before encoding the video data, which corresponds to the onPreEncodeVideoFrame callback.
*
* To observe multiple frame positions, use '|' (the OR operator).
* This callback observes AgoraVideoFramePositionPostCapture(1 << 0) and AgoraVideoFramePositionPreRenderer(1 << 1) by default.
* To conserve the system consumption, you can reduce the number of frame positions that you want to observe.
*
* @return A bit mask that controls the frame position of the video observer: AgoraVideoFramePosition.
*/
- (AgoraVideoFramePosition)getObservedFramePosition NS_SWIFT_NAME(getObservedFramePosition());
/* Unavailable Delegate Methods */
#if TARGET_OS_IPHONE
- (BOOL)onCaptureVideoFrame:(AgoraOutputVideoFrame * _Nonnull)videoFrame NS_SWIFT_NAME(onCapture(_:)) __attribute__((availability(ios,deprecated=7_0,message="Use onCaptureVideoFrame:sourceType: instead.")));
- (BOOL)onSecondaryCameraCaptureVideoFrame:(AgoraOutputVideoFrame * _Nonnull)videoFrame NS_SWIFT_NAME(onSecondaryCameraCapture(_:)) __attribute__((availability(ios,deprecated=7_0,message="Use onCaptureVideoFrame:sourceType: instead.")));
- (BOOL)onScreenCaptureVideoFrame:(AgoraOutputVideoFrame * _Nonnull)videoFrame NS_SWIFT_NAME(onScreenCapture(_:)) __attribute__((availability(ios,deprecated=7_0,message="Use onCaptureVideoFrame:sourceType: instead.")));
- (BOOL)onSecondaryScreenCaptureVideoFrame:(AgoraOutputVideoFrame * _Nonnull)videoFrame NS_SWIFT_NAME(onSecondaryScreenCapture(_:)) __attribute__((availability(ios,deprecated=7_0,message="Use onCaptureVideoFrame:sourceType: instead.")));
- (BOOL)onPreEncodeVideoFrame:(AgoraOutputVideoFrame * _Nonnull)videoFrame NS_SWIFT_NAME(onPreEncode(_:)) __attribute__((availability(ios,deprecated=7_0,message="Use onPreEncodeVideoFrame:sourceType: instead.")));
- (BOOL)onPreEncodeScreenVideoFrame:(AgoraOutputVideoFrame * _Nonnull)videoFrame NS_SWIFT_NAME(onPreEncodeScreenVideoFrame(_:)) __attribute__((availability(ios,deprecated=7_0,message="Use onPreEncodeVideoFrame:sourceType: instead.")));
#endif
#if (!(TARGET_OS_IPHONE) && (TARGET_OS_MAC))
- (BOOL)onCaptureVideoFrame:(AgoraOutputVideoFrame * _Nonnull)videoFrame NS_SWIFT_NAME(onCapture(_:)) __attribute__((availability(macos,deprecated=10_9,message="Use onCaptureVideoFrame:sourceType: instead.")));
- (BOOL)onSecondaryCameraCaptureVideoFrame:(AgoraOutputVideoFrame * _Nonnull)videoFrame NS_SWIFT_NAME(onSecondaryCameraCapture(_:)) __attribute__((availability(macos,deprecated=10_9,message="Use onCaptureVideoFrame:sourceType: instead.")));
- (BOOL)onScreenCaptureVideoFrame:(AgoraOutputVideoFrame * _Nonnull)videoFrame NS_SWIFT_NAME(onScreenCapture(_:)) __attribute__((availability(macos,deprecated=10_9,message="Use onCaptureVideoFrame:sourceType: instead.")));
- (BOOL)onSecondaryScreenCaptureVideoFrame:(AgoraOutputVideoFrame * _Nonnull)videoFrame NS_SWIFT_NAME(onSecondaryScreenCapture(_:)) __attribute__((availability(macos,deprecated=10_9,message="Use onCaptureVideoFrame:sourceType: instead.")));
- (BOOL)onPreEncodeVideoFrame:(AgoraOutputVideoFrame * _Nonnull)videoFrame NS_SWIFT_NAME(onPreEncode(_:)) __attribute__((availability(macos,deprecated=10_9,message="Use onPreEncodeVideoFrame:sourceType: instead.")));
- (BOOL)onPreEncodeScreenVideoFrame:(AgoraOutputVideoFrame * _Nonnull)videoFrame NS_SWIFT_NAME(onPreEncodeScreenVideoFrame(_:)) __attribute__((availability(macos,deprecated=10_9,message="Use onPreEncodeVideoFrame:sourceType: instead.")));
#endif
@end

View File

@@ -0,0 +1,45 @@
// Copyright (c) 2019 Agora.io. All rights reserved
// This program is confidential and proprietary to Agora.io.
// And may not be copied, reproduced, modified, disclosed to others, published
// or used, in whole or in part, without the express prior written permission
// of Agora.io.
#pragma once // NOLINT(build/header_guard)
#include "AgoraRefPtr.h"
#include <aosl/api/cpp/aosl_ares_class.h>
namespace agora {
namespace rtc {
struct ImagePayloadData {
ImagePayloadData(int seq, uint8_t* pixel, int fileSize, int w, int h, int64_t ts)
: seqid(seq),
size(fileSize),
width(w),
height(h),
timestamp(ts){
}
int seqid;
int size;
int width;
int height;
int64_t timestamp;
uint8_t* buffer;
void* privdata;
int privsize;
};
/**
* The IFileUploadService class, which enables upload file service.
*/
class IFileUploaderService : public RefCountInterface {
public:
virtual ~IFileUploaderService() {}
virtual int startImageUpload(const ImagePayloadData* imgData, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
virtual int stopImageUpload(aosl_ref_t ares = AOSL_REF_INVALID) = 0;
};
} // namespace rtc
} // namespace agora

View File

@@ -0,0 +1,178 @@
//
// Agora Media SDK
//
// Copyright (c) 2022 Agora IO. All rights reserved.
//
#pragma once
#include "AgoraBase.h"
#include "AgoraMediaBase.h"
namespace agora{
namespace rtc{
/**
* The result of IH265Transcoder interface invoking.
*/
enum H265_TRANSCODE_RESULT {
/**
* -1: Unknown error.
*/
H265_TRANSCODE_RESULT_UNKNOWN = -1,
/**
* 0: The request of operation is successfully.
*/
H265_TRANSCODE_RESULT_SUCCESS = 0,
/**
* 1: This request is invalid. Possible reasons include incorrect parameters.
*/
H265_TRANSCODE_RESULT_REQUEST_INVALID = 1,
/**
* 2: Authentication failed, please check for correctness of token.
*/
H265_TRANSCODE_RESULT_UNAUTHORIZED = 2,
/**
* 3: The token is expired, please update token.
*/
H265_TRANSCODE_RESULT_TOKEN_EXPIRED = 3,
/**
* 4: No permission to access the interface.
*/
H265_TRANSCODE_RESULT_FORBIDDEN = 4,
/**
* 5: The url of request is not found.
*/
H265_TRANSCODE_RESULT_NOT_FOUND = 5,
/**
* 6: The request encountered a conflict, please try again.
*/
H265_TRANSCODE_RESULT_CONFLICTED = 6,
/**
* 7: Content type not supported.
*/
H265_TRANSCODE_RESULT_NOT_SUPPORTED = 7,
/**
* 8: The requests are too frequent.
*/
H265_TRANSCODE_RESULT_TOO_OFTEN = 8,
/**
* 9: Internal Server Error, you can try sending the request again.
*/
H265_TRANSCODE_RESULT_SERVER_INTERNAL_ERROR = 9,
/**
* 10: Service is unavailable.
*/
H265_TRANSCODE_RESULT_SERVICE_UNAVAILABLE = 10
};
/**
* The IH265TranscoderObserver class
*/
class IH265TranscoderObserver {
public:
virtual ~IH265TranscoderObserver() {};
/**
* Use to notify the result of invoking enableTranscode interface.
* @param result Result of invoking enableTranscode interface. There are some processing advice below of result.
* - H265_TRANSCODE_RESULT_REQUEST_INVALID: Channel or uid param have a mistake, you need to check them for correctness.
* - H265_TRANSCODE_RESULT_UNAUTHORIZED: Authentication failed, please check for correctness of token.
* - H265_TRANSCODE_RESULT_TOKEN_EXPIRED: The token has expired, you need to generate a new token.
* - H265_TRANSCODE_RESULT_FORBIDDEN: You need to contact agora staff to add the vid whitelist.
* - H265_TRANSCODE_RESULT_NOT_FOUND: Indicates that the network may be faulty.
* - H265_TRANSCODE_RESULT_TOO_OFTEN: Request is too often, please request again later.
* - H265_TRANSCODE_RESULT_SERVER_INTERNAL_ERROR: The service has an internal error. A request can be made again.
*/
virtual void onEnableTranscode(H265_TRANSCODE_RESULT result) = 0;
/**
* Use to notify the result of invoking queryChannel interface.
* @param result Result of invoking queryChannel interface. There are some processing advice below of result.
* - H265_TRANSCODE_RESULT_UNAUTHORIZED: Authentication failed, please check for correctness of token.
* - H265_TRANSCODE_RESULT_TOKEN_EXPIRED: The token has expired, you need to generate a new token.
* - H265_TRANSCODE_RESULT_NOT_FOUND: Indicates that the network may be faulty or the channel param may be is empty.
* - H265_TRANSCODE_RESULT_TOO_OFTEN: Request is too often, please request again later.
* - H265_TRANSCODE_RESULT_SERVER_INTERNAL_ERROR: The service has an internal error. A request can be made again.
*
* @param originChannel Origin channel id
* @param transcodeChannel Transcode channel id
*/
virtual void onQueryChannel(H265_TRANSCODE_RESULT result, const char* originChannel, const char* transcodeChannel) = 0;
/** Use to notify the result of invoking triggerTranscode interface.
* @param result Result of invoking triggerTranscode interface. There are some processing advice below of result.
* - H265_TRANSCODE_RESULT_UNAUTHORIZED: Authentication failed, please check for correctness of token.
* - H265_TRANSCODE_RESULT_TOKEN_EXPIRED: The token has expired, you need to generate a new token.
* - H265_TRANSCODE_RESULT_NOT_FOUND: Indicates that the network may be faulty or the channel param may be is empty.
* - H265_TRANSCODE_RESULT_CONFLICTED: The request of trigger transcode is conflicted, please try again.
* - H265_TRANSCODE_RESULT_TOO_OFTEN: Request is too often, please request again later
* - H265_TRANSCODE_RESULT_SERVER_INTERNAL_ERROR: The service has an internal error. A request can be made again.
* - H265_TRANSCODE_RESULT_SERVICE_UNAVAILABLE: May be the number of transcode service is over the limit.
*/
virtual void onTriggerTranscode(H265_TRANSCODE_RESULT result) = 0;
};
/**
* The IH265Transcoder class
*/
class IH265Transcoder : public RefCountInterface {
public:
/**
* Enable transcoding for a channel.
* @param token The token for authentication.
* @param channel The unique channel name for the AgoraRTC session in the string format.
* @param uid User ID.
* @return
* - 0: Success.
* - <0: Failure.
*/
virtual int enableTranscode(const char *token, const char *channel, uid_t uid) = 0;
/**
* Query the transcoded channel of a channel.
* @param token The token for authentication.
* @param channel The unique channel name for the AgoraRTC session in the string format.
* @param uid User ID.
* @return
* - 0: Success.
* - <0: Failure.
*/
virtual int queryChannel(const char *token, const char *channel, uid_t uid) = 0;
/**
* Trigger channel transcoding.
* @param token The token for authentication.
* @param channel The unique channel name for the AgoraRTC session in the string format.
* @param uid User ID.
* @return
* - 0: Success.
* - <0: Failure.
*/
virtual int triggerTranscode(const char* token, const char* channel, uid_t uid) = 0;
/**
* Register a IH265TranscoderObserver object.
* @param observer IH265TranscoderObserver.
* @return
* - 0: Success.
* - <0: Failure.
*/
virtual int registerTranscoderObserver(IH265TranscoderObserver *observer) = 0;
/**
* Unregister a IH265TranscoderObserver object.
* @param observer IH265TranscoderObserver.
* @return
* - 0: Success.
* - <0: Failure.
*/
virtual int unregisterTranscoderObserver(IH265TranscoderObserver *observer) = 0;
protected:
virtual ~IH265Transcoder() {};
};
} // namespace rtc
} // namespace agora

View File

@@ -0,0 +1,99 @@
//
// Agora Media SDK
//
// Copyright (c) 2015 Agora IO. All rights reserved.
//
#pragma once
#include <cstdlib>
#include <stdint.h>
#ifndef OPTIONAL_ENUM_CLASS
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
#define OPTIONAL_ENUM_CLASS enum class
#else
#define OPTIONAL_ENUM_CLASS enum
#endif
#endif
#ifndef OPTIONAL_LOG_LEVEL_SPECIFIER
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
#define OPTIONAL_LOG_LEVEL_SPECIFIER LOG_LEVEL::
#else
#define OPTIONAL_LOG_LEVEL_SPECIFIER
#endif
#endif
namespace agora {
namespace commons {
/**
* Supported logging severities of SDK
*/
OPTIONAL_ENUM_CLASS LOG_LEVEL {
LOG_LEVEL_NONE = 0x0000,
LOG_LEVEL_INFO = 0x0001,
LOG_LEVEL_WARN = 0x0002,
LOG_LEVEL_ERROR = 0x0004,
LOG_LEVEL_FATAL = 0x0008,
LOG_LEVEL_API_CALL = 0x0010,
LOG_LEVEL_DEBUG = 0x0020,
};
/*
The SDK uses ILogWriter class Write interface to write logs as application
The application inherits the methods Write() to implentation their own log writ
Write has default implementation, it writes logs to files.
Application can use setLogFile() to change file location, see description of set
*/
class ILogWriter {
public:
/** user defined log Write function
@param level log level
@param message log message content
@param length log message length
@return
- 0: success
- <0: failure
*/
virtual int32_t writeLog(LOG_LEVEL level, const char* message, uint16_t length) = 0;
virtual ~ILogWriter() {}
};
enum LOG_FILTER_TYPE {
LOG_FILTER_OFF = 0,
LOG_FILTER_DEBUG = 0x080f,
LOG_FILTER_INFO = 0x000f,
LOG_FILTER_WARN = 0x000e,
LOG_FILTER_ERROR = 0x000c,
LOG_FILTER_CRITICAL = 0x0008,
LOG_FILTER_MASK = 0x80f,
};
const uint32_t MAX_LOG_SIZE = 20 * 1024 * 1024; // 20MB
const uint32_t MIN_LOG_SIZE = 128 * 1024; // 128KB
/** The default log size in kb
*/
const uint32_t DEFAULT_LOG_SIZE_IN_KB = 2048;
/** Definition of LogConfiguration
*/
struct LogConfig {
/**The log file path, default is NULL for default log path
*/
const char* filePath;
/** The log file size, KB , set 2048KB to use default log size
*/
uint32_t fileSizeInKB;
/** The log level, set LOG_LEVEL_INFO to use default log level
*/
LOG_LEVEL level;
LogConfig() : filePath(NULL), fileSizeInKB(DEFAULT_LOG_SIZE_IN_KB), level(OPTIONAL_LOG_LEVEL_SPECIFIER LOG_LEVEL_INFO) {}
};
} // namespace commons
} // namespace agora
#undef OPTIONAL_LOG_LEVEL_SPECIFIER

View File

@@ -0,0 +1,41 @@
//
// Agora SDK
//
// Copyright (c) 2021 Agora.io. All rights reserved.
//
#pragma once // NOLINT(build/header_guard)
#include "AgoraBase.h"
#include "AgoraRefPtr.h"
namespace agora {
namespace rtc {
class IMediaPlayer;
class IMediaComponentFactory {
public:
/** This method creates media player.
*/
virtual agora_refptr<IMediaPlayer> createMediaPlayer(
agora::media::base::MEDIA_PLAYER_SOURCE_TYPE type = agora::media::base::MEDIA_PLAYER_SOURCE_DEFAULT) = 0;
protected:
virtual ~IMediaComponentFactory() {}
};
} //namespace rtc
} // namespace agora
/** \addtogroup createMediaComponentFactory
@{
*/
/**
* Creates an \ref agora::rtc::IMediaComponentFactory "IMediaComponentFactory" object and returns the pointer.
*
* @return
* - The pointer to \ref agora::rtc::IMediaComponentFactory "IMediaComponentFactory": Success.
* - A null pointer: Failure.
*/
AGORA_API agora::rtc::IMediaComponentFactory* AGORA_CALL createAgoraMediaComponentFactory();
/** @} */

View File

@@ -0,0 +1,303 @@
//
// Agora Media SDK
//
// Copyright (c) 2015 Agora IO. All rights reserved.
//
#pragma once
#include "AgoraBase.h"
#include "AgoraMediaBase.h"
#include "AgoraRefPtr.h"
namespace agora {
namespace media {
/** dual-mono music output mode
*/
enum AUDIO_MIXING_DUAL_MONO_MODE {
/* 0: Original mode */
AUDIO_MIXING_DUAL_MONO_AUTO = 0,
/* 1: Left channel mode */
AUDIO_MIXING_DUAL_MONO_L = 1,
/* 2: Right channel mode */
AUDIO_MIXING_DUAL_MONO_R = 2,
/* 3: Mixed channel mode */
AUDIO_MIXING_DUAL_MONO_MIX = 3
};
/**
* The IMediaEngine class.
*/
class IMediaEngine {
public:
/**
* Registers an audio frame observer object.
*
* @note
* Ensure that you call this method before \ref IRtcEngine::joinChannel "joinChannel".
*
* @param observer A pointer to the audio frame observer object: IAudioFrameObserver,
* nullptr means unregistering observer instead.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int registerAudioFrameObserver(IAudioFrameObserver* observer) = 0;
/**
* Registers a video frame observer object.
*
* @note
* - Ensure that you call this method before joining the channel.
* - If you register an observer for video raw video data, you cannot register an IVideoEncodedFrameObserver
* object.
*
* @param observer A pointer to the video frame observer: IVideoFrameObserver.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int registerVideoFrameObserver(IVideoFrameObserver* observer) = 0;
/**
* Registers a receiver object for the encoded video image.
*
* @note
* - Ensure that you call this method before joining the channel.
*
* @param observer A pointer to the observer of the encoded video image: \ref IVideoEncodedFrameObserver
* "IVideoEncodedFrameObserver".
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int registerVideoEncodedFrameObserver(IVideoEncodedFrameObserver* observer) = 0;
/**
* Registers a face info observer object.
*
* @note
* Ensure that you call this method before \ref IRtcEngine::joinChannel "joinChannel".
*
* @param observer A pointer to the face info observer object: IFaceInfoObserver.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int registerFaceInfoObserver(IFaceInfoObserver* observer) = 0;
/**
* Pushes the external audio data to the app.
*
* @param frame The audio buffer data.
* @param trackId The audio track ID.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int pushAudioFrame(IAudioFrameObserverBase::AudioFrame* frame, rtc::track_id_t trackId = 0) = 0;
/**
* Pulls the remote audio data.
*
* After a successful method call, the app pulls the decoded and mixed audio data for playback.
*
* The difference between this method and the \ref onPlaybackAudioFrame "onPlaybackAudioFrame" is as follows:
* - `onPlaybackAudioFrame`: The SDK sends the audio data to the app once every 10 ms. Any delay in processing
* the audio frames may result in audio jitter.
* - `pullAudioFrame`: The app pulls the remote audio data. After setting the audio data parameters, the
* SDK adjusts the frame buffer and avoids problems caused by jitter in the external audio playback.
*
* @param frame The pointer to the audio frame: AudioFrame.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int pullAudioFrame(IAudioFrameObserverBase::AudioFrame* frame) = 0;
/**
* Sets the external video source.
*
* Once the external video source is enabled, the SDK prepares to accept the external video frame.
*
* @param enabled Determines whether to enable the external video source.
* - true: Enable the external video source. Once set, the SDK creates the external source and prepares
* video data from `pushVideoFrame` or `pushEncodedVideoImage`.
* - false: Disable the external video source.
* @param useTexture Determines whether to use textured video data.
* - true: Use texture, which is not supported now.
* - False: Do not use texture.
* @param sourceType Determines the type of external video source frame.
* - ENCODED_VIDEO_FRAME: The external video source is encoded.
* - VIDEO_FRAME: The external video source is not encoded.
* @param encodedVideoOption Video encoded track option, which is only used for ENCODED_VIDEO_FRAME.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setExternalVideoSource(
bool enabled, bool useTexture, EXTERNAL_VIDEO_SOURCE_TYPE sourceType = VIDEO_FRAME,
rtc::SenderOptions encodedVideoOption = rtc::SenderOptions()) = 0;
#if defined(__ANDROID__)
/**
* Sets the remote eglContext.
*
* When the engine is destroyed, the SDK will automatically release the eglContext.
*
* @param eglContext.
*
* @note
* setExternalRemoteEglContext needs to be called before joining the channel.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setExternalRemoteEglContext(void* eglContext) = 0;
#endif
/**
* Sets the external audio source.
*
* @note
* Ensure that you call this method before joining the channel.
*
* @deprecated This method is deprecated. Use createCustomAudioTrack(rtc::AUDIO_TRACK_TYPE trackType, const rtc::AudioTrackConfig& config) instead.
*
* @param enabled Determines whether to enable the external audio source:
* - true: Enable the external audio source.
* - false: (default) Disable the external audio source.
* @param sampleRate The Sample rate (Hz) of the external audio source, which can set be as
* 8000, 16000, 32000, 44100, or 48000.
* @param channels The number of channels of the external audio source, which can be set as 1 or 2:
* - 1: Mono.
* - 2: Stereo.
* @param localPlayback Enable/Disables the local playback of external audio track:
* - true: Enable local playback
* - false: (Default) Do not enable local playback
* @param publish Determines whether to publish the external audio track:
* - true: (Default) Publish the external audio track.
* - false: Don`t publish the external audio track.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setExternalAudioSource(bool enabled, int sampleRate, int channels, bool localPlayback = false, bool publish = true) __deprecated = 0;
/**
* Create a custom audio track and get the audio track id.
*
* @note Ensure that you call this method before calling `joinChannel`.
*
* @param trackType The type of custom audio track
* See AUDIO_TRACK_TYPE.
*
* @param config The config of custom audio track
* See AudioTrackConfig.
*
* @return
* - If the call is successful, SDK returns audio track id.
* - If the call fails, SDK returns 0xffffffff.
*/
virtual rtc::track_id_t createCustomAudioTrack(rtc::AUDIO_TRACK_TYPE trackType, const rtc::AudioTrackConfig& config) = 0;
/**
* Destroy custom audio track by trackId
*
* @param trackId The custom audio track id.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int destroyCustomAudioTrack(rtc::track_id_t trackId) = 0;
/**
* Sets the external audio sink.
*
* This method applies to scenarios where you want to use external audio
* data for playback. After calling the \ref IRtcEngine::initialize "initialize"
* method and pass value of false in the `enableAudioDevice` member in the RtcEngineContext struct, you can call
* the \ref agora::media::IMediaEngine::pullAudioFrame "pullAudioFrame" method to pull the remote audio data, process
* it, and play it with the audio effects that you want.
*
* @note
* Once you call the \ref IRtcEngine::initialize "initialize" method and pass value of false in the `enableAudioDevice`
* member in the RtcEngineContext struct, the app will not retrieve any audio data from the
* \ref agora::media::IAudioFrameObserver::onPlaybackAudioFrame "onPlaybackAudioFrame" callback.
*
* @param enabled Sets whether or not to the external audio sink
* - true: Enables the external audio sink.
* - false: Disables the external audio sink.
* @param sampleRate Sets the sample rate (Hz) of the external audio sink, which can be set as 16000, 32000, 44100 or 48000.
* @param channels Sets the number of audio channels of the external
* audio sink:
* - 1: Mono.
* - 2: Stereo.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setExternalAudioSink(bool enabled, int sampleRate, int channels) = 0;
/**
* Sets the external audio track.
*
* @note
* Ensure that you call this method before joining the channel.
*
* @param trackId The custom audio track id.
* @param enabled Enable/Disables the local playback of external audio track:
* - true: Enable local playback
* - false: Do not enable local playback
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int enableCustomAudioLocalPlayback(rtc::track_id_t trackId, bool enabled) = 0;
/**
* Pushes the external video frame to the app.
*
* @param frame The external video frame: ExternalVideoFrame.
* @param videoTrackId The id of the video track.
* - 0: Success.
* - < 0: Failure.
*/
virtual int pushVideoFrame(base::ExternalVideoFrame* frame, unsigned int videoTrackId = 0) = 0;
/**
* Pushes the encoded video image to the app.
* @param imageBuffer A pointer to the video image.
* @param length The data length.
* @param videoEncodedFrameInfo The reference to the information of the encoded video frame:
* \ref agora::rtc::EncodedVideoFrameInfo "EncodedVideoFrameInfo".
* @param videoTrackId The id of the video track.
* - 0: Success.
* - < 0: Failure.
*/
virtual int pushEncodedVideoImage(const unsigned char* imageBuffer, size_t length,
const agora::rtc::EncodedVideoFrameInfo& videoEncodedFrameInfo,
unsigned int videoTrackId = 0) = 0;
/**
* @hide For internal usage only
*/
virtual int addVideoFrameRenderer(IVideoFrameObserver *renderer) = 0;
/**
* @hide For internal usage only
*/
virtual int removeVideoFrameRenderer(IVideoFrameObserver *renderer) = 0;
virtual void release() = 0;
protected:
virtual ~IMediaEngine() {}
};
} // namespace media
} // namespace agora

View File

@@ -0,0 +1,633 @@
//
// Agora SDK
//
// Copyright (c) 2020 Agora.io. All rights reserved.
//
#pragma once // NOLINT(build/header_guard)
#include "AgoraBase.h"
#include "AgoraMediaBase.h"
#include "AgoraMediaPlayerTypes.h"
#include "AgoraRefPtr.h"
namespace agora {
namespace base {
class IAgoraService;
}
namespace rtc {
class ILocalAudioTrack;
class ILocalVideoTrack;
class IMediaPlayerSourceObserver;
class IMediaPlayerCustomDataProvider;
/**
* The IMediaPlayerEntity class provides access to a media player entity. If yout want to playout
* multiple media sources simultaneously, create multiple media player source objects.
*/
class IMediaPlayer : public RefCountInterface {
protected:
virtual ~IMediaPlayer() {}
public:
virtual int initialize(base::IAgoraService* agora_service) = 0;
/**
* Get unique media player id of the media player entity.
* @return
* - >= 0: The source id of this media player entity.
* - < 0: Failure.
*/
virtual int getMediaPlayerId() const = 0;
/**
* Opens a media file with a specified URL.
* @param url The URL of the media file that you want to play.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int open(const char* url, int64_t startPos) = 0;
/**
* @brief Open a media file with a media file source.
* @param source Media file source that you want to play, see `MediaSource`
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int openWithMediaSource(const media::base::MediaSource &source) = 0;
/**
* Plays the media file.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int play() = 0;
/**
* Pauses playing the media file.
*/
virtual int pause() = 0;
/**
* Stops playing the current media file.
*/
virtual int stop() = 0;
/**
* Resumes playing the media file.
*/
virtual int resume() = 0;
/**
* Sets the current playback position of the media file.
* @param newPos The new playback position (ms).
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int seek(int64_t newPos) = 0;
/** Sets the pitch of the current media file.
* @param pitch Sets the pitch of the local music file by chromatic scale. The default value is 0,
* which means keeping the original pitch. The value ranges from -12 to 12, and the pitch value between
* consecutive values is a chromatic value. The greater the absolute value of this parameter, the
* higher or lower the pitch of the local music file.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setAudioPitch(int pitch) = 0;
/**
* Gets the duration of the media file.
* @param duration A reference to the duration of the media file.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getDuration(int64_t& duration) = 0;
/**
* Gets the current playback position of the media file.
* @param currentPosition A reference to the current playback position (ms).
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getPlayPosition(int64_t& pos) = 0;
virtual int getStreamCount(int64_t& count) = 0;
virtual int getStreamInfo(int64_t index, media::base::PlayerStreamInfo* info) = 0;
/**
* Sets whether to loop the media file for playback.
* @param loopCount the number of times looping the media file.
* - 0: Play the audio effect once.
* - 1: Play the audio effect twice.
* - -1: Play the audio effect in a loop indefinitely, until stopEffect() or stop() is called.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setLoopCount(int loopCount) = 0;
/**
* Change playback speed
* @param speed the value of playback speed ref [50-400]
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setPlaybackSpeed(int speed) = 0;
/**
* Slect playback audio track of the media file
* @param index the index of the audio track in media file
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int selectAudioTrack(int index) = 0;
/**
* Selects multi audio track of the media file for playback or publish to channel.
* @param playoutTrackIndex The index of the audio track in media file for local playback.
* @param publishTrackIndex The index of the audio track in the media file published to the remote.
*
* @note
* You can obtain the streamIndex of the audio track by calling getStreamInfo..
* If you want to use selectMultiAudioTrack, you need to open the media file with openWithMediaSource and set enableMultiAudioTrack to true.
*
* @return
* - 0: Success.
* - < 0: Failure. See {@link media::base::MEDIA_PLAYER_REASON MEDIA_PLAYER_REASON}.
* - -2: Invalid argument. Argument must be greater than or equal to zero.
* - -8: Invalid State.You must open the media file with openWithMediaSource and set enableMultiAudioTrack to true
*/
virtual int selectMultiAudioTrack(int playoutTrackIndex, int publishTrackIndex) = 0;
/**
* change player option before play a file
* @param key the key of the option param
* @param value the value of option param
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setPlayerOption(const char* key, int value) = 0;
/**
* change player option before play a file
* @param key the key of the option param
* @param value the value of option param
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setPlayerOption(const char* key, const char* value) = 0;
/**
* take screenshot while playing video
* @param filename the filename of screenshot file
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int takeScreenshot(const char* filename) = 0;
/**
* select internal subtitles in video
* @param index the index of the internal subtitles
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int selectInternalSubtitle(int index) = 0;
/**
* set an external subtitle for video
* @param url The URL of the subtitle file that you want to load.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setExternalSubtitle(const char* url) = 0;
virtual media::base::MEDIA_PLAYER_STATE getState() = 0;
/**
* @brief Turn mute on or off
*
* @param muted Whether to mute on
* @return int < 0 on behalf of an error, the value corresponds to one of MEDIA_PLAYER_REASON
*/
virtual int mute(bool muted) = 0;
/**
* @brief Get mute state
*
* @param[out] muted Whether is mute on
* @return int < 0 on behalf of an error, the value corresponds to one of MEDIA_PLAYER_REASON
*/
virtual int getMute(bool& muted) = 0;
/**
* @brief Adjust playback volume
*
* @param volume The volume value to be adjusted
* The volume can be adjusted from 0 to 400:
* 0: mute;
* 100: original volume;
* 400: Up to 4 times the original volume (with built-in overflow protection).
* @return int < 0 on behalf of an error, the value corresponds to one of MEDIA_PLAYER_REASON
*/
virtual int adjustPlayoutVolume(int volume) = 0;
/**
* @brief Get the current playback volume
*
* @param[out] volume
* @return int < 0 on behalf of an error, the value corresponds to one of MEDIA_PLAYER_REASON
*/
virtual int getPlayoutVolume(int& volume) = 0;
/**
* @brief adjust publish signal volume
*
* @return int < 0 on behalf of an error, the value corresponds to one of MEDIA_PLAYER_REASON
*/
virtual int adjustPublishSignalVolume(int volume) = 0;
/**
* @brief get publish signal volume
*
* @return int < 0 on behalf of an error, the value corresponds to one of MEDIA_PLAYER_REASON
*/
virtual int getPublishSignalVolume(int& volume) = 0;
/**
* @brief Set video rendering view
*
* @param view view object, windows platform is HWND
* @return int < 0 on behalf of an error, the value corresponds to one of MEDIA_PLAYER_REASON
*/
virtual int setView(media::base::view_t view) = 0;
/**
* @brief Set video display mode
*
* @param renderMode Video display mode
* @return int < 0 on behalf of an error, the value corresponds to one of MEDIA_PLAYER_REASON
*/
virtual int setRenderMode(media::base::RENDER_MODE_TYPE renderMode) = 0;
/**
* Registers a media player source observer.
*
* Once the media player source observer is registered, you can use the observer to monitor the state change of the media player.
* @param observer The pointer to the IMediaPlayerSourceObserver object.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int registerPlayerSourceObserver(IMediaPlayerSourceObserver* observer) = 0;
/**
* Releases the media player source observer.
* @param observer The pointer to the IMediaPlayerSourceObserver object.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int unregisterPlayerSourceObserver(IMediaPlayerSourceObserver* observer) = 0;
/**
* Register the audio frame observer.
*
* @param observer The pointer to the IAudioFrameObserver object.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int registerAudioFrameObserver(media::IAudioPcmFrameSink* observer) = 0;
/**
* Registers an audio observer.
*
* @param observer The audio observer, reporting the reception of each audio
* frame. See
* \ref media::IAudioPcmFrameSink "IAudioFrameObserver" for
* details.
* @param mode Use mode of the audio frame. See #RAW_AUDIO_FRAME_OP_MODE_TYPE.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int registerAudioFrameObserver(media::IAudioPcmFrameSink* observer,
RAW_AUDIO_FRAME_OP_MODE_TYPE mode) = 0;
/**
* Releases the audio frame observer.
* @param observer The pointer to the IAudioFrameObserver object.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int unregisterAudioFrameObserver(media::IAudioPcmFrameSink* observer) = 0;
/**
* @brief Register the player video observer
*
* @param observer observer object
* @return int < 0 on behalf of an error, the value corresponds to one of MEDIA_PLAYER_REASON
*/
virtual int registerVideoFrameObserver(media::base::IVideoFrameObserver* observer) = 0;
/**
* @brief UnRegister the player video observer
*
* @param observer observer object
* @return int < 0 on behalf of an error, the value corresponds to one of MEDIA_PLAYER_REASON
*/
virtual int unregisterVideoFrameObserver(agora::media::base::IVideoFrameObserver* observer) = 0;
/**
* Registers the audio frame spectrum observer.
*
* @param observer The pointer to the {@link media::base::IAudioSpectrumObserver IAudioSpectrumObserver} object.
* @param intervalInMS Sets the time interval(ms) between two consecutive audio spectrum callback.
* The default value is 100. This param should be larger than 10.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int registerMediaPlayerAudioSpectrumObserver(media::IAudioSpectrumObserver* observer, int intervalInMS) = 0;
/**
* Releases the audio frame spectrum observer.
* @param observer The pointer to the {@link media::base::IAudioSpectrumObserver IAudioSpectrumObserver} object.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int unregisterMediaPlayerAudioSpectrumObserver(media::IAudioSpectrumObserver* observer) = 0;
/**
* @brief Set dual-mono output mode of the music file.
*
* @param mode dual mono mode. See #agora::media::AUDIO_DUAL_MONO_MODE
*/
virtual int setAudioDualMonoMode(agora::media::base::AUDIO_DUAL_MONO_MODE mode) = 0;
/**
* get sdk version and build number of player SDK.
* @return String of the SDK version.
*
* @deprecated This method is deprecated.
*/
virtual const char* getPlayerSdkVersion() = 0;
/**
* Get the current play src.
* @return
* - current play src of raw bytes.
*/
virtual const char* getPlaySrc() = 0;
/**
* Open the Agora CDN media source.
* @param src The src of the media file that you want to play.
* @param startPos The playback position (ms).
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int openWithAgoraCDNSrc(const char* src, int64_t startPos) = 0;
/**
* Gets the number of Agora CDN lines.
* @return
* - > 0: number of CDN.
* - <= 0: Failure.
*/
virtual int getAgoraCDNLineCount() = 0;
/**
* Switch Agora CDN lines.
* @param index Specific CDN line index.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int switchAgoraCDNLineByIndex(int index) = 0;
/**
* Gets the line of the current CDN.
* @return
* - >= 0: Specific line.
* - < 0: Failure.
*/
virtual int getCurrentAgoraCDNIndex() = 0;
/**
* Enable automatic CDN line switching.
* @param enable Whether enable.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int enableAutoSwitchAgoraCDN(bool enable) = 0;
/**
* Update the CDN source token and timestamp.
* @param token token.
* @param ts ts.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int renewAgoraCDNSrcToken(const char* token, int64_t ts) = 0;
/**
* Switch the CDN source when open a media through "openWithAgoraCDNSrc" API
* @param src Specific src.
* @param syncPts Live streaming must be set to false.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int switchAgoraCDNSrc(const char* src, bool syncPts = false) = 0;
/**
* Switch the media source when open a media through "open" API
* @param src Specific src.
* @param syncPts Live streaming must be set to false.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int switchSrc(const char* src, bool syncPts = true) = 0;
/**
* Preload a media source
* @param src Specific src.
* @param startPos The starting position (ms) for playback. Default value is 0.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int preloadSrc(const char* src, int64_t startPos) = 0;
/**
* Play a pre-loaded media source
* @param src Specific src.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int playPreloadedSrc(const char* src) = 0;
/**
* Unload a preloaded media source
* @param src Specific src.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int unloadSrc(const char* src) = 0;
/**
* Set spatial audio params for the music file. It can be called after the media player
* was created.
*
* @param params See #agora::SpatialAudioParams. If it's
* not set, then the spatial audio will be disabled; or it will be enabled.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setSpatialAudioParams(const SpatialAudioParams& params) = 0;
/**
* Set sound position params for the music file. It can be called after the media player
* was created.
*
*@param pan The sound position of the music file. The value ranges from -1.0 to 1.0:
*- 0.0: the music sound comes from the front.
*- -1.0: the music sound comes from the left.
*- 1.0: the music sound comes from the right.
*@param gain Gain of the music. The value ranges from 0.0 to 100.0. The default value is 100.0 (the original gain of the music). The smaller the value, the less the gain.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setSoundPositionParams(float pan, float gain) = 0;
};
/**
* This class is used to set and manage the player cache, implemented in the
* form of a singleton, independent of the player.
*/
class IMediaPlayerCacheManager {
public:
/**
* Delete the longest used cache file in order to release some of the cache file disk usage.
* (usually used when the cache quota notification is received)
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int removeAllCaches() = 0;
/**
* Remove the latest media resource cache file.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int removeOldCache() = 0;
/**
* Remove the cache file by uri, setting by MediaSource.
* @param uri URIidentify the uniqueness of the property, Set from `MeidaSource`
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int removeCacheByUri(const char *uri) = 0;
/**
* Set cache file path that files will be saved to.
* @param path file path.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setCacheDir(const char *path) = 0;
/**
* Set the maximum number of cached files.
* @param count maximum number of cached files.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setMaxCacheFileCount(int count) = 0;
/**
* Set the maximum size of cache file disk usage.
* @param cacheSize total size of the largest cache file.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setMaxCacheFileSize(int64_t cacheSize) = 0;
/**
* Whether to automatically delete old cache files when the cache file usage reaches the limit.
* @param enable enable the player to automatically clear the cache.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int enableAutoRemoveCache(bool enable) = 0;
/**
* Get the cache directory.
* @param path cache path, recieve a pointer to be copied to.
* @param length the length to be copied.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getCacheDir(char* path, int length) = 0;
/**
* Get the maximum number of cached files.
* @return
* > 0: file count.
* - < 0: Failure.
*/
virtual int getMaxCacheFileCount() = 0;
/**
* Get the total size of the largest cache file
* @return
* > 0: file size.
* - < 0: Failure.
*/
virtual int64_t getMaxCacheFileSize() = 0;
/**
* Get the number of all cache files.
* @return
* > 0: file count.
* - < 0: Failure.
*/
virtual int getCacheFileCount() = 0;
virtual ~IMediaPlayerCacheManager(){};
};
} //namespace rtc
} // namespace agora
AGORA_API agora::rtc::IMediaPlayerCacheManager* AGORA_CALL getMediaPlayerCacheManager();

View File

@@ -0,0 +1,493 @@
//
// Agora SDK
//
// Copyright (c) 2018 Agora.io. All rights reserved.
//
#pragma once // NOLINT(build/header_guard)
#include "AgoraBase.h"
#include "AgoraMediaBase.h"
#include "AgoraMediaPlayerTypes.h"
#include "AgoraRefPtr.h"
namespace agora {
namespace rtc {
class IMediaPlayerSourceObserver;
/**
* The IMediaPlayerSource class provides access to a media player source. To playout multiple media sources simultaneously,
* create multiple media player source objects.
*/
class IMediaPlayerSource : public RefCountInterface {
protected:
virtual ~IMediaPlayerSource() {}
public:
/**
* Gets the unique source ID of the media player source.
* @return
* - >=0: The source ID of this media player source.
* - < 0: Failure.
*/
virtual int getSourceId() const = 0;
/**
* Opens a media file with a specified URL.
* @param url The path of the media file. Both the local path and online path are supported.
* @param startPos The starting position (ms) for playback. Default value is 0.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int open(const char* url, int64_t startPos) = 0;
/**
* Opens a media file with a media file source.
* @param source Media file source that you want to play, see `MediaSource`
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int openWithMediaSource(const media::base::MediaSource &source) = 0;
/**
* Plays the media file.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int play() = 0;
/**
* Pauses the playback.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int pause() = 0;
/**
* Stops the playback.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int stop() = 0;
/**
* Resumes the playback.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int resume() = 0;
/**
* Sets the playback position of the media file.
* @param newPos The new playback position (ms).
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int seek(int64_t newPos) = 0;
/**
* Gets the duration of the media file.
* @param [out] duration A reference to the duration of the media file.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getDuration(int64_t& duration) = 0;
/**
* Gets the current playback position of the media file.
* @param [out] pos A reference to the current playback position (ms).
* @return
* - 0: Success.
* - < 0: Failure. See {@link media::base::MEDIA_PLAYER_REASON MEDIA_PLAYER_REASON}.
*/
virtual int getPlayPosition(int64_t& pos) = 0;
/**
* Gets the number of the media streams in the media source.
* @param [out] count The number of the media streams in the media source.
* @return
* - 0: Success.
* - < 0: Failure. See {@link media::base::MEDIA_PLAYER_REASON MEDIA_PLAYER_REASON}.
*/
virtual int getStreamCount(int64_t& count) = 0;
/**
* Gets the detailed information of a media stream.
* @param index The index of the media stream.
* @param [out] info The detailed information of the media stream. See \ref media::base::PlayerStreamInfo "PlayerStreamInfo" for details.
* @return
* - 0: Success.
* - < 0: Failure. See {@link media::base::MEDIA_PLAYER_REASON MEDIA_PLAYER_REASON}.
*/
virtual int getStreamInfo(int64_t index, media::base::PlayerStreamInfo* info) = 0;
/**
* Sets whether to loop the media file for playback.
* @param loopCount The number of times of looping the media file.
* - 0: Play the media file once.
* - 1: Play the media file twice.
* - -1: Play the media file in a loop indefinitely, until {@link stop} is called.
* @return
* - 0: Success.
* - < 0: Failure. See {@link media::base::MEDIA_PLAYER_REASON MEDIA_PLAYER_REASON}.
*/
virtual int setLoopCount(int64_t loopCount) = 0;
/**
* Changes the playback speed.
* @param speed The playback speed ref [50-400].
* @return
* - 0: Success.
* - < 0: Failure. See {@link media::base::MEDIA_PLAYER_REASON MEDIA_PLAYER_REASON}.
*/
virtual int setPlaybackSpeed(int speed) = 0;
/**
* Selects an audio track of the media file for playback.
* @param index The index of the audio track in media file.
* @return
* - 0: Success.
* - < 0: Failure. See {@link media::base::MEDIA_PLAYER_REASON MEDIA_PLAYER_REASON}.
*/
virtual int selectAudioTrack(int64_t index) = 0;
/**
* Selects multi audio track of the media file for playback or publish to channel.
* @param playoutTrackIndex The index of the audio track in media file for local playback.
* @param publishTrackIndex The index of the audio track in the media file published to the remote.
*
* @note
* You can obtain the streamIndex of the audio track by calling getStreamInfo..
* If you want to use selectMultiAudioTrack, you need to open the media file with openWithMediaSource and set enableMultiAudioTrack to true.
*
* @return
* - 0: Success.
* - < 0: Failure. See {@link media::base::MEDIA_PLAYER_REASON MEDIA_PLAYER_REASON}.
* - -2: Invalid argument. Argument must be greater than or equal to zero.
* - -8: Invalid State.You must open the media file with openWithMediaSource and set enableMultiAudioTrack to true
*/
virtual int selectMultiAudioTrack(int playoutTrackIndex, int publishTrackIndex) = 0;
/**
* Changes the player option before playing a file.
* @param key The key of the option paramemter.
* @param value The value of option parameter.
* @return
* - 0: Success.
* - < 0: Failure. See {@link media::base::MEDIA_PLAYER_REASON MEDIA_PLAYER_REASON}.
*/
virtual int setPlayerOption(const char* key, int64_t value) = 0;
/**
* Changes the player option before playing a file.
* @param key The key of the option paramemter.
* @param value The value of option parameter.
* @return
* - 0: Success.
* - < 0: Failure. See {@link media::base::MEDIA_PLAYER_REASON MEDIA_PLAYER_REASON}.
*/
virtual int setPlayerOption(const char* key, const char* value) = 0;
/**
* Takes a screenshot when playing a video file.
* @param filename The filename of the screenshot file.
* @return
* - 0: Success.
* - < 0: Failure. See {@link media::base::MEDIA_PLAYER_REASON MEDIA_PLAYER_REASON}.
*/
virtual int takeScreenshot(const char* filename) = 0;
/**
* Selects internal subtitles for a video file.
* @param index The index of the internal subtitles.
* @return
* - 0: Success.
* - < 0: Failure. See {@link media::base::MEDIA_PLAYER_REASON MEDIA_PLAYER_REASON}.
*/
virtual int selectInternalSubtitle(int64_t index) = 0;
/**
* Sets an external subtitle file for a video file.
* @param url The URL of the subtitle file.
* @return
* - 0: Success.
* - < 0: Failure. See {@link media::base::MEDIA_PLAYER_REASON MEDIA_PLAYER_REASON}.
*/
virtual int setExternalSubtitle(const char* url) = 0;
/**
* Gets the playback state.
* @return The current playback state. See {@link media::base::MEDIA_PLAYER_STATE MEDIA_PLAYER_STATE} for details.
*/
virtual media::base::MEDIA_PLAYER_STATE getState() = 0;
/**
* Registers a media player source observer.
*
* Once the media player source observer is registered, you can use the observer to monitor the state change of the media player.
* @param observer The pointer to the IMediaPlayerSourceObserver object.
* @return
* - 0: Success.
* - < 0: Failure. See {@link media::base::MEDIA_PLAYER_REASON MEDIA_PLAYER_REASON}.
*/
virtual int registerPlayerSourceObserver(IMediaPlayerSourceObserver* observer) = 0;
/**
* Releases the media player source observer.
* @param observer The pointer to the IMediaPlayerSourceObserver object.
* @return
* - 0: Success.
* - < 0: Failure. See {@link media::base::MEDIA_PLAYER_REASON MEDIA_PLAYER_REASON}.
*/
virtual int unregisterPlayerSourceObserver(IMediaPlayerSourceObserver* observer) = 0;
/**
* Registers the audio frame observer.
*
* @param observer The pointer to the {@link media::IAudioPcmFrameSink observer} object.
* @return
* - 0: Success.
* - < 0: Failure. See {@link media::base::MEDIA_PLAYER_REASON MEDIA_PLAYER_REASON}.
*/
virtual int registerAudioFrameObserver(media::IAudioPcmFrameSink* observer) = 0;
/**
* Releases the audio frame observer.
* @param observer The pointer to the {@link media::IAudioPcmFrameSink observer} object.
* @return
* - 0: Success.
* - < 0: Failure. See {@link media::base::MEDIA_PLAYER_REASON MEDIA_PLAYER_REASON}.
*/
virtual int unregisterAudioFrameObserver(media::IAudioPcmFrameSink* observer) = 0;
/**
* Open the Agora CDN media source.
* @param src The src of the media file that you want to play.
* @param startPos The playback position (ms).
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int openWithAgoraCDNSrc(const char* src, int64_t startPos) = 0;
/**
* Gets the number of Agora CDN lines.
* @return
* - > 0: number of CDN.
* - <= 0: Failure.
*/
virtual int getAgoraCDNLineCount() = 0;
/**
* Switch Agora CDN lines.
* @param index Specific CDN line index.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int switchAgoraCDNLineByIndex(int index) = 0;
/**
* Gets the line of the current CDN.
* @return
* - >= 0: Specific line.
* - < 0: Failure.
*/
virtual int getCurrentAgoraCDNIndex() = 0;
/**
* Enable automatic CDN line switching.
* @param enable Whether enable.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int enableAutoSwitchAgoraCDN(bool enable) = 0;
/**
* Update the CDN source token and timestamp.
* @param token token.
* @param ts ts.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int renewAgoraCDNSrcToken(const char* token, int64_t ts) = 0;
/**
* Switch the CDN source when open a media through "openWithAgoraCDNSrc" API
* @param src Specific src.
* @param syncPts Live streaming must be set to false.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int switchAgoraCDNSrc(const char* src, bool syncPts = false) = 0;
/**
* Switch the media source when open a media through "open" API
* @param src Specific src.
* @param syncPts Live streaming must be set to false.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int switchSrc(const char* src, bool syncPts) = 0;
/**
* Preload a media source
* @param src Specific src.
* @param startPos The starting position (ms) for playback. Default value is 0.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int preloadSrc(const char* src, int64_t startPos) = 0;
/**
* Unload a preloaded media source
* @param src Specific src.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int unloadSrc(const char* src) = 0;
/**
* Play a pre-loaded media source
* @param src Specific src.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int playPreloadedSrc(const char* src) = 0;
};
/**
* This class class reports runtime events to the applications.
*/
class IMediaPlayerSourceObserver {
public:
virtual ~IMediaPlayerSourceObserver() {}
/**
* @brief Reports the playback state change.
*
* When the state of the playback changes, the SDK triggers this callback to report the new playback state and the reason or error for the change.
* @param state The new playback state after change. See {@link media::base::MEDIA_PLAYER_STATE MEDIA_PLAYER_STATE}.
* @param reason The player's error code. See {@link media::base::MEDIA_PLAYER_REASON MEDIA_PLAYER_REASON}.
*/
virtual void onPlayerSourceStateChanged(media::base::MEDIA_PLAYER_STATE state,
media::base::MEDIA_PLAYER_REASON reason) = 0;
/**
* @brief Reports current playback progress.
*
* The callback occurs once every one second during the playback and reports the current playback progress.
* @param positionMs Current playback progress (milisecond).
* @param timestampMs Current NTP(Network Time Protocol) time (milisecond).
*/
virtual void onPositionChanged(int64_t positionMs, int64_t timestampMs) = 0;
/**
* @brief Reports the playback event.
*
* - After calling the `seek` method, the SDK triggers the callback to report the results of the seek operation.
* - After calling the `selectAudioTrack` method, the SDK triggers the callback to report that the audio track changes.
*
* @param eventCode The playback event. See {@link media::base::MEDIA_PLAYER_EVENT MEDIA_PLAYER_EVENT}.
* @param elapsedTime The playback elapsed time.
* @param message The playback message.
*/
virtual void onPlayerEvent(media::base::MEDIA_PLAYER_EVENT eventCode, int64_t elapsedTime, const char* message) = 0;
/**
* @brief Occurs when the metadata is received.
*
* The callback occurs when the player receives the media metadata and reports the detailed information of the media metadata.
* @param data The detailed data of the media metadata.
* @param length The data length (bytes).
*/
virtual void onMetaData(const void* data, int length) = 0;
/**
* @brief Triggered when play buffer updated, once every 1 second
*
* @param int cached buffer during playing, in milliseconds
*/
virtual void onPlayBufferUpdated(int64_t playCachedBuffer) = 0;
/**
* @brief Triggered when the player preloadSrc
*
* @param event
*/
virtual void onPreloadEvent(const char* src, media::base::PLAYER_PRELOAD_EVENT event) = 0;
/**
* @brief Occurs when one playback of the media file is completed.
*/
virtual void onCompleted() = 0;
/**
* @brief AgoraCDN Token has expired and needs to be set up with renewAgoraCDNSrcToken(const char* src).
*/
virtual void onAgoraCDNTokenWillExpire() = 0;
/**
* @brief Reports current playback source bitrate changed.
* @brief Reports current playback source info changed.
*
* @param from Streaming media information before the change.
* @param to Streaming media information after the change.
*/
virtual void onPlayerSrcInfoChanged(const media::base::SrcInfo& from, const media::base::SrcInfo& to) = 0;
/**
* @brief Triggered when media player information updated.
*
* @param info Include information of media player.
*/
virtual void onPlayerInfoUpdated(const media::base::PlayerUpdatedInfo& info) = 0;
/**
* @brief Triggered every 1 second, reports the statistics of the files being cached.
*
* @param stats Cached file statistics.
*/
virtual void onPlayerCacheStats(const media::base::CacheStatistics& stats) {
(void)stats;
}
/**
* @brief Triggered every 1 second, reports the statistics of the media stream being played.
*
* @param stats The statistics of the media stream.
*/
virtual void onPlayerPlaybackStats(const media::base::PlayerPlaybackStats& stats) {
(void)stats;
}
/**
* @brief Triggered every 200 millisecond ,update player current volume range [0,255]
*
* @param volume volume of current player.
*/
virtual void onAudioVolumeIndication(int volume) = 0;
};
} //namespace rtc
} // namespace agora

View File

@@ -0,0 +1,89 @@
//
// Agora SDK
//
// Copyright (c) 2022 Agora.io. All rights reserved.
//
#pragma once // NOLINT(build/header_guard)
#include "AgoraBase.h"
#include "AgoraMediaBase.h"
namespace agora {
namespace rtc {
class IMediaRecorder : public RefCountInterface {
protected:
virtual ~IMediaRecorder() {}
public:
/**
* Registers the IMediaRecorderObserver object.
*
* @since v4.0.0
*
* @note Call this method before the startRecording method.
*
* @param callback The callbacks for recording audio and video streams. See \ref IMediaRecorderObserver.
*
* @return
* - 0(ERR_OK): Success.
* - < 0: Failure:
*/
virtual int setMediaRecorderObserver(media::IMediaRecorderObserver* callback) = 0;
/**
* Starts recording the local or remote audio and video.
*
* @since v4.0.0
*
* After successfully calling \ref IRtcEngine::createMediaRecorder "createMediaRecorder" to get the media recorder object
* , you can call this method to enable the recording of the local audio and video.
*
* This method can record the following content:
* - The audio captured by the local microphone and encoded in AAC format.
* - The video captured by the local camera and encoded by the SDK.
* - The audio received from remote users and encoded in AAC format.
* - The video received from remote users.
*
* The SDK can generate a recording file only when it detects the recordable audio and video streams; when there are
* no audio and video streams to be recorded or the audio and video streams are interrupted for more than five
* seconds, the SDK stops recording and triggers the
* \ref IMediaRecorderObserver::onRecorderStateChanged "onRecorderStateChanged" (RECORDER_STATE_ERROR, RECORDER_ERROR_NO_STREAM)
* callback.
*
* @note Call this method after joining the channel.
*
* @param config The recording configurations. See MediaRecorderConfiguration.
*
* @return
* - 0(ERR_OK): Success.
* - < 0: Failure:
* - `-1(ERR_FAILED)`: IRtcEngine does not support the request because the remote user did not subscribe to the target channel or the media streams published by the local user during remote recording.
* - `-2(ERR_INVALID_ARGUMENT)`: The parameter is invalid. Ensure the following:
* - The specified path of the recording file exists and is writable.
* - The specified format of the recording file is supported.
* - The maximum recording duration is correctly set.
* - During remote recording, ensure the user whose media streams you want record did join the channel.
* - `-4(ERR_NOT_SUPPORTED)`: IRtcEngine does not support the request due to one of the following reasons:
* - The recording is ongoing.
* - The recording stops because an error occurs.
* - No \ref IMediaRecorderObserver object is registered.
*/
virtual int startRecording(const media::MediaRecorderConfiguration& config) = 0;
/**
* Stops recording the audio and video.
*
* @since v4.0.0
*
* @note After calling \ref IMediaRecorder::startRecording "startRecording", if you want to stop the recording,
* you must call `stopRecording`; otherwise, the generated recording files might not be playable.
*
*
* @return
* - 0(ERR_OK): Success.
* - < 0: Failure:
*/
virtual int stopRecording() = 0;
};
} //namespace rtc
} // namespace agora

View File

@@ -0,0 +1,332 @@
//
// Agora SDK
// Copyright (c) 2019 Agora.io. All rights reserved.
//
// Created by xiaohua.lu in 2020-03.
// CodeStyle: Google C++
//
#pragma once // NOLINT(build/header_guard)
#include "AgoraBase.h"
#include "AgoraMediaBase.h"
#include "AgoraMediaPlayerTypes.h"
#include "AgoraRefPtr.h"
namespace agora {
namespace rtc {
class IMediaStreamingSourceObserver;
/**
* @brief The error code of streaming source
*
*/
enum STREAMING_SRC_ERR {
STREAMING_SRC_ERR_NONE = 0, ///< no error
STREAMING_SRC_ERR_UNKNOWN = 1, ///< unknown error
STREAMING_SRC_ERR_INVALID_PARAM = 2, ///< invalid parameter
STREAMING_SRC_ERR_BAD_STATE = 3, ///< bad status
STREAMING_SRC_ERR_NO_MEM = 4, ///< not enough memory
STREAMING_SRC_ERR_BUFFER_OVERFLOW = 5, ///< buffer overflow
STREAMING_SRC_ERR_BUFFER_UNDERFLOW = 6, ///< buffer underflow
STREAMING_SRC_ERR_NOT_FOUND = 7, ///< buffer underflow
STREAMING_SRC_ERR_TIMEOUT = 8, ///< buffer underflow
STREAMING_SRC_ERR_EXPIRED = 9, ///< expired
STREAMING_SRC_ERR_UNSUPPORTED = 10, ///< unsupported
STREAMING_SRC_ERR_NOT_EXIST = 11, ///< component not exist
STREAMING_SRC_ERR_EXIST = 12, ///< component already exist
STREAMING_SRC_ERR_OPEN = 13, ///< fail to IO open
STREAMING_SRC_ERR_CLOSE = 14, ///< fail to IO close
STREAMING_SRC_ERR_READ = 15, ///< fail to IO read
STREAMING_SRC_ERR_WRITE = 16, ///< fail to IO write
STREAMING_SRC_ERR_SEEK = 17, ///< fail to IO seek
STREAMING_SRC_ERR_EOF = 18, ///< reach to IO EOF, can do nothing
STREAMING_SRC_ERR_CODECOPEN = 19, ///< fail to codec open
STREAMING_SRC_ERR_CODECCLOSE = 20, ///< fail to codec close
STREAMING_SRC_ERR_CODECPROC = 21, ///< fail to codec process
};
/**
* @brief The state machine of Streaming Source
*
*/
enum STREAMING_SRC_STATE {
STREAMING_SRC_STATE_CLOSED = 0, ///< streaming source still closed, can do nothing
STREAMING_SRC_STATE_OPENING = 1, ///< after call open() method and start parsing streaming source
STREAMING_SRC_STATE_IDLE = 2, ///< streaming source is ready waiting for play
STREAMING_SRC_STATE_PLAYING = 3, ///< after call play() method, playing & pushing the AV data
STREAMING_SRC_STATE_SEEKING = 4, ///< after call seek() method, start seeking poisition
STREAMING_SRC_STATE_EOF = 5, ///< The position is located at end, can NOT playing
STREAMING_SRC_STATE_ERROR = 6, ///< The error status and can do nothing except close
};
/**
* @brief The input SEI data
*
*/
struct InputSeiData {
int32_t type; ///< SEI type
int64_t timestamp; ///< the frame timestamp which be attached
int64_t frame_index; ///< the frame index which be attached
uint8_t* private_data; ///< SEI really data
int32_t data_size; ///< size of really data
};
/**
* @brief The IMediaStreamingSource class provides access to a media streaming source demuxer.
* To playout multiple stream sources simultaneously,
* create multiple media stream source objects.
*/
class IMediaStreamingSource : public RefCountInterface {
public:
virtual ~IMediaStreamingSource() {};
/**
* @brief Opens a media streaming source with a specified URL.
* @param url The path of the media file. Both the local path and online path are supported.
* @param startPos The starting position (ms) for pushing. Default value is 0.
* @param auto_play whether start playing after opened
* @return
* - 0: Success.
* - < 0: Failure
*/
virtual int open(const char* url, int64_t start_pos, bool auto_play = true) = 0;
/**
* @brief Close current media streaming source
* @return
* - 0: Success.
* - < 0: Failure
*/
virtual int close() = 0;
/**
* @brief Gets the unique source ID of the streaming source.
* @return
* - ≧ 0: The source ID of this media player source.
* - < 0: Failure.
*/
virtual int getSourceId() const = 0;
/**
* @brief Retrieve whether video stream is valid
* @return: valid or invalid
*/
virtual bool isVideoValid() = 0;
/**
* @brief Retrieve whether audio stream is valid
* @return: valid or invalid
*/
virtual bool isAudioValid() = 0;
/**
* @brief Gets the duration of the streaming source.
* @param [out] duration A reference to the duration of the media file.
* @return
* - 0: Success.
* - < 0: Failure. See {@link STREAMINGSRC_ERR}.
*/
virtual int getDuration(int64_t& duration) = 0;
/**
* @brief Gets the number of the streming source
* @param [out] count The number of the media streams in the media source.
* @return
* - 0: Success.
* - < 0: Failure. See {@link STREAMINGSRC_ERR}.
*/
virtual int getStreamCount(int64_t& count) = 0;
/**
* @brief Gets the detailed information of a media stream.
* @param index The index of the media stream.
* @param [out] out_info The detailed information of the media stream. See \ref media::base::PlayerStreamInfo "PlayerStreamInfo" for details.
* @return
* - 0: Success.
* - < 0: Failure. See {@link STREAMINGSRC_ERR}.
*/
virtual int getStreamInfo(int64_t index, media::base::PlayerStreamInfo* out_info) = 0;
/**
* @brief Sets whether to loop the streaming source for playback.
* @param loop_count The number of times of looping the media file.
* - 1: Play the media file once.
* - 2: Play the media file twice.
* - <= 0: Play the media file in a loop indefinitely, until {@link stop} is called.
* @return
* - 0: Success.
* - < 0: Failure. See {@link STREAMINGSRC_ERR}.
*/
virtual int setLoopCount(int64_t loop_count) = 0;
/**
* @brief Play & push the streaming source.
* @return
* - 0: Success.
* - < 0: Failure. See {@link STREAMINGSRC_ERR}.
*/
virtual int play() = 0;
/**
* @brief Pauses the playing & pushing of the streaming source, Keep current position.
* @return
* - 0: Success.
* - < 0: Failure. See {@link STREAMINGSRC_ERR}.
*/
virtual int pause() = 0;
/**
* @brief Stop the playing & pushing of the streaming source, set the position to 0.
* @return
* - 0: Success.
* - < 0: Failure.See {@link STREAMINGSRC_ERR}.
*/
virtual int stop() = 0;
/**
* @brief Sets the playback position of the streaming source.
* After seek done, it will return to previous status
* @param newPos The new playback position (ms).
* @return
* - 0: Success.
* - < 0: Failure. See {@link STREAMINGSRC_ERR}.
*/
virtual int seek(int64_t new_pos) = 0;
/**
* @brief Gets the current playback position of the media file.
* @param [out] pos A reference to the current playback position (ms).
* @return
* - 0: Success.
* - < 0: Failure. See {@link STREAMINGSRC_ERR}.
*/
virtual int getCurrPosition(int64_t& pos) = 0;
/**
* @breif Gets the status of current streaming source.
* @return The current state machine
*/
virtual STREAMING_SRC_STATE getCurrState() = 0;
/**
* @brief append the SEI data which can be sent attached to video packet
* @param type SEI type
* @param timestamp the video frame timestamp which attached to
* @param frame_index the video frame timestamp which attached to
*
* @return
* - 0: Success.
* - < 0: Failure. See {@link STREAMINGSRC_ERR}.
*/
virtual int appendSeiData(const InputSeiData& inSeiData) = 0;
/**
* Registers a media player source observer.
*
* Once the media player source observer is registered, you can use the observer to monitor the state change of the media player.
* @param observer The pointer to the IMediaStreamingSource object.
* @return
* - 0: Success.
* - < 0: Failure. See {@link STREAMINGSRC_ERR}.
*/
virtual int registerObserver(IMediaStreamingSourceObserver* observer) = 0;
/**
* Releases the media player source observer.
* @param observer The pointer to the IMediaStreamingSource object.
* @return
* - 0: Success.
* - < 0: Failure. See {@link STREAMINGSRC_ERR}.
*/
virtual int unregisterObserver(IMediaStreamingSourceObserver* observer) = 0;
/**
* @brief Parse a media information with a specified URL.
* @param url : The path of the media file. Both the local path and online path are supported.
* @param video_info : The output video information, It means no video track while video_info.streamIndex less than 0
* @param audio_info : The output audio information, It means no audio track while audio_info.streamIndex less than 0
* @return
* - 0: Success.
* - < 0: Failure
*/
virtual int parseMediaInfo(const char* url,
media::base::PlayerStreamInfo& video_info,
media::base::PlayerStreamInfo& audio_info) = 0;
};
/**
* @brief This observer interface of media streaming source
*/
class IMediaStreamingSourceObserver {
public:
virtual ~IMediaStreamingSourceObserver() {};
/**
* @brief Reports the playback state change.
* When the state of the playback changes,
* the SDK triggers this callback to report the new playback state
* and the reason or error for the change.
* @param state The new playback state after change. See {@link STREAMING_SRC_STATE}.
* @param ec The player's error code. See {@link STREAMINGSRC_ERR}.
*/
virtual void onStateChanged(STREAMING_SRC_STATE state, STREAMING_SRC_ERR err_code) = 0;
/**
* @brief Triggered when file is opened
* @param err_code The error code
* @return None
*/
virtual void onOpenDone(STREAMING_SRC_ERR err_code) = 0;
/**
* @brief Triggered when seeking is done
* @param err_code The error code
* @return None
*/
virtual void onSeekDone(STREAMING_SRC_ERR err_code) = 0;
/**
* @brief Triggered when playing is EOF
* @param progress_ms the progress position
* @param repeat_count means repeated count of playing
*/
virtual void onEofOnce(int64_t progress_ms, int64_t repeat_count) = 0;
/**
* @brief Reports current playback progress.
* The callback triggered once every one second during the playing status
* @param position_ms Current playback progress (millisecond).
*/
virtual void onProgress(int64_t position_ms) = 0;
/**
* @brief Occurs when the metadata is received.
* The callback occurs when the player receives the media metadata
* and reports the detailed information of the media metadata.
* @param data The detailed data of the media metadata.
* @param length The data length (bytes).
*/
virtual void onMetaData(const void* data, int length) = 0;
};
} //namespace rtc
} // namespace agora

View File

@@ -0,0 +1,581 @@
//
// Agora Media SDK
//
// Created by FanYuanYuan in 2022-05.
// Copyright (c) 2022 Agora IO. All rights reserved.
//
#pragma once
#include "AgoraRefPtr.h"
#include "IAgoraMediaPlayer.h"
namespace agora {
namespace rtc {
/**
* Modes for playing songs.
*/
typedef enum
{
/**
* 0: The music player is in the origin mode, which means playing the original song.
*/
kMusicPlayModeOriginal = 0,
/**
* 1: The music player is in the accompany mode, which means playing the accompaniment only.
*/
kMusicPlayModeAccompany = 1,
/**
* 2: The music player is in the lead sing mode, which means playing the lead vocals.
*/
kMusicPlayModeLeadSing = 2,
} MusicPlayMode;
typedef enum
{
/**
* 0: No error occurs and preload succeeds.
*/
kPreloadStateCompleted = 0,
/**
* 1: A general error occurs.
*/
kPreloadStateFailed = 1,
/**
* 2: The media file is preloading.
*/
kPreloadStatePreloading = 2,
/**
* 3: The media file is removed.
*/
kPreloadStateRemoved = 3,
} PreloadState;
typedef enum
{
/**
* 0: No error occurs and request succeeds.
*/
kMusicContentCenterReasonOk = 0,
/**
* 1: A general error occurs.
*/
kMusicContentCenterReasonError = 1,
/**
* 2: The gateway error. There are several possible reasons:
* - Token is expired. Check if your token is expired.
* - Token is invalid. Check the type of token you passed in.
* - Network error. Check your network.
*/
kMusicContentCenterReasonGateway = 2,
/**
* 3: Permission and resource error. There are several possible reasons:
* - Your appid may not have the mcc permission. Please contact technical support
* - The resource may not exist. Please contact technical support
*/
kMusicContentCenterReasonPermissionAndResource = 3,
/**
* 4: Internal data parse error. Please contact technical support
*/
kMusicContentCenterReasonInternalDataParse = 4,
/**
* 5: Music loading error. Please contact technical support
*/
kMusicContentCenterReasonMusicLoading = 5,
/**
* 6: Music decryption error. Please contact technical support
*/
kMusicContentCenterReasonMusicDecryption = 6,
/**
* 7: Http internal error. Please retry later.
*/
kMusicContentCenterReasonHttpInternalError = 7,
} MusicContentCenterStateReason;
typedef struct
{
/**
* Name of the music chart
*/
const char* chartName;
/**
* Id of the music chart, which is used to get music list
*/
int32_t id;
} MusicChartInfo;
enum MUSIC_CACHE_STATUS_TYPE {
/**
* 0: Music is already cached.
*/
MUSIC_CACHE_STATUS_TYPE_CACHED = 0,
/**
* 1: Music is being cached.
*/
MUSIC_CACHE_STATUS_TYPE_CACHING = 1
};
struct MusicCacheInfo {
/**
* The songCode of music.
*/
int64_t songCode;
/**
* The cache status of the music.
*/
MUSIC_CACHE_STATUS_TYPE status;
MusicCacheInfo():songCode(0), status(MUSIC_CACHE_STATUS_TYPE_CACHED) {}
};
class MusicChartCollection : public RefCountInterface {
public:
virtual int getCount() = 0;
virtual MusicChartInfo* get(int index) = 0;
protected:
virtual ~MusicChartCollection() = default;
};
struct MvProperty
{
/**
* The resolution of the mv
*/
const char* resolution;
/**
* The bandwidth of the mv
*/
const char* bandwidth;
};
struct ClimaxSegment
{
/**
* The start time of climax segment
*/
int32_t startTimeMs;
/**
* The end time of climax segment
*/
int32_t endTimeMs;
};
struct Music
{
/**
* The songCode of music
*/
int64_t songCode;
/**
* The name of music
*/
const char* name;
/**
* The singer of music
*/
const char* singer;
/**
* The poster url of music
*/
const char* poster;
/**
* The release time of music
*/
const char* releaseTime;
/**
* The duration (in seconds) of music
*/
int32_t durationS;
/**
* The type of music
* 1, mp3 with instrumental accompaniment and original
* 2, mp3 only with instrumental accompaniment
* 3, mp3 only with original
* 4, mp4 with instrumental accompaniment and original
* 5, mv only
* 6, new type mp4 with instrumental accompaniment and original
* detail at document of music media center
*/
int32_t type;
/**
* The pitch type of music.
* 1, xml lyric has pitch
* 2, lyric has no pitch
*/
int32_t pitchType;
/**
* The number of lyrics available for the music
*/
int32_t lyricCount;
/**
* The lyric list of music
* 0, xml
* 1, lrc
*/
int32_t* lyricList;
/**
* The number of climax segments of the music
*/
int32_t climaxSegmentCount;
/**
* The climax segment list of music
*/
ClimaxSegment* climaxSegmentList;
/**
* The number of mv of the music
* If this value is greater than zero, it means the current music has MV resource
*/
int32_t mvPropertyCount;
/**
* The mv property list of music
*/
MvProperty* mvPropertyList;
};
class MusicCollection : public RefCountInterface {
public:
virtual int getCount() = 0;
virtual int getTotal() = 0;
virtual int getPage() = 0;
virtual int getPageSize() = 0;
virtual Music* getMusic(int32_t index) = 0;
protected:
virtual ~MusicCollection() = default;
};
class IMusicContentCenterEventHandler {
public:
/**
* The music chart result callback; occurs when getMusicCharts method is called.
*
* @param requestId The request id is same as that returned by getMusicCharts.
* @param result The result of music chart collection
* @param reason The status of the request. See MusicContentCenterStateReason
*/
virtual void onMusicChartsResult(const char* requestId, agora_refptr<MusicChartCollection> result, MusicContentCenterStateReason reason) = 0;
/**
* Music collection, occurs when getMusicCollectionByMusicChartId or searchMusic method is called.
*
* @param requestId The request id is same as that returned by getMusicCollectionByMusicChartId or searchMusic
* @param result The result of music collection
* @param reason The status of the request. See MusicContentCenterStateReason
*/
virtual void onMusicCollectionResult(const char* requestId, agora_refptr<MusicCollection> result, MusicContentCenterStateReason reason) = 0;
/**
* Lyric url callback of getLyric, occurs when getLyric is called
*
* @param requestId The request id is same as that returned by getLyric
* @param songCode Song code
* @param lyricUrl The lyric url of this music
* @param reason The status of the request. See MusicContentCenterStateReason
*/
virtual void onLyricResult(const char* requestId, int64_t songCode, const char* lyricUrl, MusicContentCenterStateReason reason) = 0;
/**
* Simple info callback of getSongSimpleInfo, occurs when getSongSimpleInfo is called
*
* @param requestId The request id is same as that returned by getSongSimpleInfo.
* @param songCode Song code
* @param simpleInfo The metadata of the music.
* @param reason The status of the request. See MusicContentCenterStateReason
*/
virtual void onSongSimpleInfoResult(const char* requestId, int64_t songCode, const char* simpleInfo, MusicContentCenterStateReason reason) = 0;
/**
* Preload process callback, occurs when preload is called
*
* @param requestId The request id is same as that returned by preload.
* @param songCode Song code
* @param percent Preload progress (0 ~ 100)
* @param lyricUrl The lyric url of this music
* @param state Preload state; see PreloadState.
* @param reason The status of the request. See MusicContentCenterStateReason
*/
virtual void onPreLoadEvent(const char* requestId, int64_t songCode, int percent, const char* lyricUrl, PreloadState state, MusicContentCenterStateReason reason) = 0;
virtual ~IMusicContentCenterEventHandler() {};
};
struct MusicContentCenterConfiguration {
/**
* The app ID of the project that has enabled the music content center
*/
const char *appId;
/**
* Music content center need token to connect with server
*/
const char *token;
/**
* The user ID when using music content center. It can be different from that of the rtc product.
*/
int64_t mccUid;
/**
* The max number which the music content center caches cannot exceed 50.
*/
int32_t maxCacheSize;
/**
* @technical preview
*/
const char* mccDomain;
/**
* Event handler to get callback result.
*/
IMusicContentCenterEventHandler* eventHandler;
MusicContentCenterConfiguration():appId(nullptr),token(nullptr),eventHandler(nullptr),mccUid(0),maxCacheSize(10), mccDomain(nullptr){}
MusicContentCenterConfiguration(const char*appid,const char* token,int64_t id,IMusicContentCenterEventHandler* handler,int32_t maxSize = 10, const char* apiurl = nullptr):
appId(appid),token(token),mccUid(id),eventHandler(handler),maxCacheSize(maxSize), mccDomain(apiurl){}
};
class IMusicPlayer : public IMediaPlayer {
protected:
virtual ~IMusicPlayer() {};
public:
IMusicPlayer() {};
using IMediaPlayer::open;
/**
* Open a media file with specified parameters.
*
* @param songCode The identifier of the media file that you want to play.
* @param startPos The playback position (ms) of the music file.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int open(int64_t songCode, int64_t startPos = 0) = 0;
/**
* Set the mode for playing songs.
* You can call this method to switch from original to accompaniment or lead vocals.
* If you do not call this method to set the mode, the SDK plays the accompaniment by default.
*
* @param model The playing mode.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setPlayMode(MusicPlayMode mode) = 0;
};
class IMusicContentCenter
{
protected:
virtual ~IMusicContentCenter(){};
public:
IMusicContentCenter() {};
/**
* Initializes the IMusicContentCenter
* Set token of music content center and other params
*
* @param configuration
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int initialize(const MusicContentCenterConfiguration & configuration) = 0;
/**
* Renew token of music content center
*
* @param token The new token.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int renewToken(const char* token) = 0;
/**
* release music content center resource.
*
*/
virtual void release() = 0;
/**
* register event handler.
*/
virtual int registerEventHandler(IMusicContentCenterEventHandler* eventHandler) = 0;
/**
* unregister event handler.
*/
virtual int unregisterEventHandler() = 0;
/**
* Creates a music player source object and return its pointer.
* @return
* - The pointer to \ref rtc::IMusicPlayer "IMusicPlayer",
* if the method call succeeds.
* - The empty pointer NULL, if the method call fails.
*/
virtual agora_refptr<IMusicPlayer> createMusicPlayer() = 0;
/**
* Destroy a music player source object and return result.
* @param music_player The pointer to \ref rtc::IMusicPlayer "IMusicPlayer".
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int destroyMusicPlayer(agora_refptr<IMusicPlayer> music_player) = 0;
/**
* Get music chart collection of music.
* If the method call succeeds, get result from the
* \ref agora::rtc::IMusicContentCenterEventHandler::onMusicChartsResult
* "onMusicChartsResult" callback
* @param requestId The request id you will get of this query, format is uuid.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getMusicCharts(agora::util::AString& requestId) = 0;
/**
* Get music collection of the music chart by musicChartId and page info.
* If the method call success, get result from the
* \ref agora::rtc::IMusicContentCenterEventHandler::onMusicCollectionResult
* "onMusicCollectionResult" callback
* @param requestId The request id you will get of this query, format is uuid.
* @param musicChartId The music chart id obtained from getMusicCharts.
* @param page The page of the music chart, starting from 1
* @param pageSize The page size, max is 50.
* @param jsonOption The ext param, default is null.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getMusicCollectionByMusicChartId(agora::util::AString& requestId, int32_t musicChartId, int32_t page, int32_t pageSize, const char* jsonOption = nullptr) = 0;
/**
* Search music by keyword and page info.
* If the method call success, get result from the
* \ref agora::rtc::IMusicContentCenterEventHandler::onMusicCollectionResult
* "onMusicCollectionResult" callback
* @param requestId The request id you will get of this query, format is uuid.
* @param keyWord The key word to search.
* @param page The page of music search result , start from 1.
* @param pageSize The page size, max is 50.
* @param jsonOption The ext param, default is null.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int searchMusic(agora::util::AString& requestId, const char* keyWord, int32_t page, int32_t pageSize, const char* jsonOption = nullptr) = 0;
/**
* Preload a media file with specified parameters.
*
* @deprecated This method is deprecated. Use preload(int64_t songCode) instead.
*
* @param songCode The identifier of the media file that you want to play.
* @param jsonOption The ext param, default is null.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int preload(int64_t songCode, const char* jsonOption) __deprecated = 0;
/**
* Preload a media file with specified parameters.
*
* @param requestId The request id you will get of this query, format is uuid.
* @param songCode The identifier of the media file that you want to play.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int preload(agora::util::AString& requestId, int64_t songCode) = 0;
/**
* Remove a media file cache
*
* @param songCode The identifier of the media file that you want to play.
* @return
* - 0: Success; the cached media file is removed.
* - < 0: Failure.
*/
virtual int removeCache(int64_t songCode) = 0;
/**
* Get cached media files.
* Before calling this API, you should allocate a memory buffer that stores the cached media file information, and pass the pointer of the buffer as the input parameter cacheInfo, and set the size of the memory buffer to cacheInfoSize.
* The sample code below illustrates how to request the cached media file information:
*
* cacheInfoSize = 10 // Allocate a memory buffer of 10 MusicCacheInfo size
* agora::rtc::MusicCacheInfo *infos = new agora::rtc::MusicCacheInfo[cacheInfoSize];
* int ret = self.imcc->getCaches(infos, cacheInfoSize);
* if (ret < 0) { // error occurred!
* return;
* }
* std::cout << "the cache size:" << cacheInfoSize << std::endl; // The cache size: 5
*
*
* @param cacheInfo An output parameter; A pointer to the memory buffer that stores the cached media file information. The memory buffer pointed to by cacheInfo should be allocated by yourself before calling this API.
* @param cacheInfoSize
* - Input: The number of MusicCacheInfo's size that you get from the memory.
* - Output: The actual number of MusicCacheInfo struct that is returned.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getCaches(MusicCacheInfo *cacheInfo, int32_t* cacheInfoSize) = 0;
/**
* Check if the media file is preloaded
*
* @param songCode The identifier of the media file that you want to play.
* @return
* - 0: Success, file is preloaded.
* - < 0: Failure.
*/
virtual int isPreloaded(int64_t songCode) = 0;
/**
* Get lyric of the music.
*
* @param requestId The request id you will get of this query, format is uuid.
* @param songCode The identifier of the media file that you want to play.
* @param lyricType The type of the lyric file. 0:xml or 1:lrc.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getLyric(agora::util::AString& requestId, int64_t songCode, int32_t lyricType = 0) = 0;
/**
* Gets the metadata of a specific music. Once this method is called, the SDK triggers the onSongSimpleInfoResult callback to report the metadata of the music.
*
* @param requestId The request id you will get of this query, format is uuid.
* @param songCode The identifier of the media file.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getSongSimpleInfo(agora::util::AString& requestId, int64_t songCode) = 0;
/**
* Get internal songCodeKey from songCode and jsonOption
*
* @param songCode The identifier of the media file.
* @param jsonOption An extention parameter. The default value is null. its a json-format string and the `key` and `value` can be customized according to your scenarios.
* @param internalSongCode The identifier of internal
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getInternalSongCode(int64_t songCode, const char* jsonOption, int64_t& internalSongCode) = 0;
};
} // namespace rtc
} // namespace agora

View File

@@ -0,0 +1,308 @@
//
// Agora Engine SDK
//
// Created by minbo in 2019-10.
// Copyright (c) 2019 Agora.io. All rights reserved.
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#pragma once // NOLINT(build/header_guard)
#include "AgoraRefPtr.h"
// external key
/**
* set the range of ports available for connection
* @example "{\"rtc.udp_port_range\":[4500, 5000]}"
*/
#define KEY_RTC_UDP_PORT_RANGE "rtc.udp_port_range"
/**
* set the list of ports available for connection
* @example "{\"rtc.udp_port_list\":[4501, 4502, 4503, 4504, 4505, 4506]}"
*/
#define KEY_RTC_UDP_PORT_LIST "rtc.udp_port_list"
/**
* get the fd of sending socket available for connection
* note: set method is not supported.
*/
#define KEY_RTC_UDP_SEND_FD "rtc.udp_send_fd"
/**
* set the video encoder mode (hardware or software)
*/
#define KEY_RTC_VIDEO_ENABLED_HW_ENCODER "engine.video.enable_hw_encoder"
#define KEY_RTC_VIDEO_HARDWARE_ENCODEING "che.hardware_encoding" // deprecated, please use engine.video.enable_hw_encoder
/**
* set the hardware video encoder provider (nv for nvidia or qsv for intel)
*/
#define KEY_RTC_VIDEO_HW_ENCODER_PROVIDER "engine.video.hw_encoder_provider"
/**
* set the video decoder mode (hardware or software)
*/
#define KEY_RTC_VIDEO_ENABLED_HW_DECODER "engine.video.enable_hw_decoder"
#define KEY_RTC_VIDEO_HARDWARE_DECODING "che.hardware_decoding" // deprecated, please use engine.video.enable_hw_decoder
/**
* set the hardware video decoder provider (h264_cuvid(default) or h264_qsv)
*/
#define KEY_RTC_VIDEO_HW_DECODER_PROVIDER "engine.video.hw_decoder_provider"
/**
* override the lua policy
*/
#define KEY_RTC_VIDEO_OVERRIDE_SMALLVIDEO_NOT_USE_HWENC_POLICY "engine.video.override_smallvideo_not_use_hwenc_policy"
/**
* enable/disable video packet retransmission, enabled by default
*/
#define KEY_RTC_VIDEO_RESEND "rtc.video_resend"
/**
* enable/disable audio packet retransmission, enabled by default
*/
#define KEY_RTC_AUDIO_RESEND "rtc.audio_resend"
/**
* set the bitrate ratio for video
*/
#define KEY_RTC_VIDEO_BITRATE_ADJUST_RATIO "rtc.video.bitrate_adjust_ratio"
/**
* set the minbitrate / bitrate ratio for video
*/
#define KEY_RTC_VIDEO_MINBITRATE_RATIO "rtc.video.minbitrate_ratio"
/**
* set the degradation preference
*/
#define KEY_RTC_VIDEO_DEGRADATION_PREFERENCE "rtc.video.degradation_preference"
/**
* set the degradation fps down step
*/
#define KEY_RTC_VIDEO_DEGRADATION_FPS_DOWN_STEP "rtc.video.degradation_fps_down_step"
/**
* set the degradation fps up step
*/
#define KEY_RTC_VIDEO_DEGRADATION_FPS_UP_STEP "rtc.video.degradation_fps_up_step"
/**
* set the duration ms for connection lost callback
*/
#define KEY_RTC_CONNECTION_LOST_PERIOD "rtc.connection_lost_period"
/**
* set the local ip
*/
#define KEY_RTC_LOCAL_IP "rtc.local.ip"
/**
* set the network interface
*/
#define KEY_RTC_NETWORK_INTERFACE "rtc.network.interface"
/**
* set the video codec type, such as "H264", "JPEG"
*/
#define KEY_RTC_VIDEO_MINOR_STREAM_CODEC_INDEX "engine.video.minor_stream_codec_index"
#define KEY_RTC_VIDEO_CODEC_INDEX "che.video.videoCodecIndex"
/**
* only use average QP for quality scaling
*/
#define KEY_RTC_VIDEO_QUALITY_SCALE_ONLY_ON_AVERAGE_QP "engine.video.quality_scale_only_on_average_qp"
/**
* low bound for quality scaling
*/
#define KEY_RTC_VIDEO_H264_QP_THRESHOLD_LOW "engine.video.h264_qp_thresholds_low"
/**
* high bound for quality scaling
*/
#define KEY_RTC_VIDEO_H264_QP_THRESHOLD_HIGH "engine.video.h264_qp_thresholds_high"
namespace agora {
namespace util {
template <class T>
class CopyableAutoPtr;
class IString;
typedef CopyableAutoPtr<IString> AString;
} // namespace util
namespace base {
class IAgoraParameter : public RefCountInterface {
public:
/**
* release the resource
*/
virtual void release() = 0;
/**
* set bool value of the json
* @param [in] key
* the key name
* @param [in] value
* the value
* @return return 0 if success or an error code
*/
virtual int setBool(const char* key, bool value) = 0;
/**
* set int value of the json
* @param [in] key
* the key name
* @param [in] value
* the value
* @return return 0 if success or an error code
*/
virtual int setInt(const char* key, int value) = 0;
/**
* set unsigned int value of the json
* @param [in] key
* the key name
* @param [in] value
* the value
* @return return 0 if success or an error code
*/
virtual int setUInt(const char* key, unsigned int value) = 0;
/**
* set double value of the json
* @param [in] key
* the key name
* @param [in] value
* the value
* @return return 0 if success or an error code
*/
virtual int setNumber(const char* key, double value) = 0;
/**
* set string value of the json
* @param [in] key
* the key name
* @param [in] value
* the value
* @return return 0 if success or an error code
*/
virtual int setString(const char* key, const char* value) = 0;
/**
* set object value of the json
* @param [in] key
* the key name
* @param [in] value
* the value
* @return return 0 if success or an error code
*/
virtual int setObject(const char* key, const char* value) = 0;
/**
* set array value of the json
* @param [in] key
* the key name
* @param [in] value
* the value
* @return return 0 if success or an error code
*/
virtual int setArray(const char* key, const char* value) = 0;
/**
* get bool value of the json
* @param [in] key
* the key name
* @param [in, out] value
* the value
* @return return 0 if success or an error code
*/
virtual int getBool(const char* key, bool& value) = 0;
/**
* get int value of the json
* @param [in] key
* the key name
* @param [in, out] value
* the value
* @return return 0 if success or an error code
*/
virtual int getInt(const char* key, int& value) = 0;
/**
* get unsigned int value of the json
* @param [in] key
* the key name
* @param [in, out] value
* the value
* @return return 0 if success or an error code
*/
virtual int getUInt(const char* key, unsigned int& value) = 0;
/**
* get double value of the json
* @param [in] key
* the key name
* @param [in, out] value
* the value
* @return return 0 if success or an error code
*/
virtual int getNumber(const char* key, double& value) = 0;
/**
* get string value of the json
* @param [in] key
* the key name
* @param [in, out] value
* the value
* @return return 0 if success or an error code
*/
virtual int getString(const char* key, agora::util::AString& value) = 0;
/**
* get a child object value of the json
* @param [in] key
* the key name
* @param [in, out] value
* the value
* @return return 0 if success or an error code
*/
virtual int getObject(const char* key, agora::util::AString& value) = 0;
/**
* get array value of the json
* @param [in] key
* the key name
* @param [in, out] value
* the value
* @return return 0 if success or an error code
*/
virtual int getArray(const char* key, const char* args, agora::util::AString& value) = 0;
/**
* set parameters of the sdk or engine
* @param [in] parameters
* the parameters
* @return return 0 if success or an error code
*/
virtual int setParameters(const char* parameters) = 0;
virtual int convertPath(const char* filePath, agora::util::AString& value) = 0;
protected:
virtual ~IAgoraParameter() {}
};
} // namespace base
} // namespace agora

View File

@@ -0,0 +1,92 @@
//
// Agora SDK
//
// Copyright (c) 2021 Agora.io. All rights reserved.
//
#pragma once // NOLINT(build/header_guard)
#include "AgoraBase.h"
#include "AgoraRefPtr.h"
namespace agora {
namespace base {
class IAgoraService;
}
namespace rtc {
class ILocalAudioTrack;
class IRtcEngineEventHandler;
/**
The states of the rhythm player.
*/
enum RHYTHM_PLAYER_STATE_TYPE {
/** 810: The rhythm player is idle. */
RHYTHM_PLAYER_STATE_IDLE = 810,
/** 811: The rhythm player is opening files. */
RHYTHM_PLAYER_STATE_OPENING,
/** 812: Files opened successfully, the rhythm player starts decoding files. */
RHYTHM_PLAYER_STATE_DECODING,
/** 813: Files decoded successfully, the rhythm player starts mixing the two files and playing back them locally. */
RHYTHM_PLAYER_STATE_PLAYING,
/** 814: The rhythm player is starting to fail, and you need to check the error code for detailed failure reasons. */
RHYTHM_PLAYER_STATE_FAILED,
};
/**
The reason codes of the rhythm player.
*/
enum RHYTHM_PLAYER_REASON {
/** 0: The rhythm player works well. */
RHYTHM_PLAYER_REASON_OK = 0,
/** 1: The rhythm player occurs a internal error. */
RHYTHM_PLAYER_REASON_FAILED = 1,
/** 801: The rhythm player can not open the file. */
RHYTHM_PLAYER_REASON_CAN_NOT_OPEN = 801,
/** 802: The rhythm player can not play the file. */
RHYTHM_PLAYER_REASON_CAN_NOT_PLAY,
/** 803: The file duration over the limit. The file duration limit is 1.2 seconds */
RHYTHM_PLAYER_REASON_FILE_OVER_DURATION_LIMIT,
};
/**
* The configuration of rhythm player,
* which is set in startRhythmPlayer or configRhythmPlayer.
*/
struct AgoraRhythmPlayerConfig {
/**
* The number of beats per measure. The range is 1 to 9.
* The default value is 4,
* which means that each measure contains one downbeat and three upbeats.
*/
int beatsPerMeasure;
/*
* The range is 60 to 360.
* The default value is 60,
* which means that the rhythm player plays 60 beats in one minute.
*/
int beatsPerMinute;
AgoraRhythmPlayerConfig() : beatsPerMeasure(4), beatsPerMinute(60) {}
};
/**
* The IRhythmPlayer class provides access to a rhythm player entity.
* A rhythm player synthesizes beats, plays them locally, and pushes them remotely.
*/
class IRhythmPlayer : public RefCountInterface {
protected:
virtual ~IRhythmPlayer() {}
public:
static agora_refptr<IRhythmPlayer> Create();
virtual int initialize(base::IAgoraService* agora_service, IRtcEngineEventHandler* event_handler, bool is_pass_thru_mode) = 0;
virtual int playRhythm(const char* sound1, const char* sound2, const AgoraRhythmPlayerConfig& config) = 0;
virtual int stopRhythm() = 0;
virtual int configRhythmPlayer(const AgoraRhythmPlayerConfig& config) = 0;
virtual agora_refptr<ILocalAudioTrack> getRhythmPlayerTrack() = 0;
};
} //namespace rtc
} // namespace agora

View File

@@ -0,0 +1,716 @@
//
// Agora Rtm SDK
//
// Created by junhao Wang in 2018-05.
// Copyright (c) 2018 Agora IO. All rights reserved.
//
#pragma once
#include <stdint.h>
#include <aosl/api/cpp/aosl_ares_class.h>
namespace agora {
namespace rtm {
enum PEER_MESSAGE_STATE {
PEER_MESSAGE_INIT = 0,
PEER_MESSAGE_FAILURE = 1,
PEER_MESSAGE_PEER_UNREACHABLE = 2,
PEER_MESSAGE_RECEIVED_BY_PEER = 3,
PEER_MESSAGE_SENT_TIMEOUT = 4,
};
/**
* The login error code.
*/
enum LOGIN_ERR_CODE {
/**
* 0: Login succeeds. No error occurs.
*/
LOGIN_ERR_OK = 0,
/**
* 1: Login fails for reasons unknown.
*/
LOGIN_ERR_UNKNOWN = 1,
/**
* 2: The server rejects the login, either because the user has already logged in, or because
* the RTM service is not initialized.
*/
LOGIN_ERR_REJECTED = 2, // ALREADY LOGIN OR NOT INITIALIZED, SERVER REJECT
/**
* 3: Invalid login arguments.
*/
LOGIN_ERR_INVALID_ARGUMENT = 3,
/**
* 4: The App ID is invalid.
*/
LOGIN_ERR_INVALID_APP_ID = 4,
/**
* 5: The token is invalid.
*/
LOGIN_ERR_INVALID_TOKEN = 5,
/**
* 6: The login is rejected because the token has expired.
*/
LOGIN_ERR_TOKEN_EXPIRED = 6,
/**
* 7: Authentication of the RTMP token fails.
*/
LOGIN_ERR_NOT_AUTHORIZED = 7,
/**
* 8: The login times out. The current timeout is set as six seconds.
*/
LOGIN_ERR_TIMEOUT = 8,
};
/**
* The logout error code.
*/
enum LOGOUT_ERR_CODE {
/**
* 0: Logout succeeds. No error occurs.
*/
LOGOUT_ERR_OK = 0,
/**
* 1: Logout fails.
*/
LOGOUT_ERR_REJECTED = 1,
};
/**
* The connection state.
*/
enum CONNECTION_STATE {
/**
* 1: The SDK has logged in the RTM service.
*/
CONNECTION_STATE_CONNECTED = 1,
/**
* 2: The initial state. The SDK is disconnected from the RTM service.
*/
CONNECTION_STATE_DISCONNECTED = 2,
/**
* 3: The SDK gives up logging in the RTM service, mainly because another instance has logged in the RTM
* service with the same user ID.
*
* Call the logout() method before calling login to log in the RTM service again.
*/
CONNECTION_STATE_ABORTED = 3,
};
/**
* The state of the channel message.
*/
enum CHANNEL_MESSAGE_STATE {
/**
* 1: The channel message is received by the server.
*/
CHANNEL_MESSAGE_RECEIVED_BY_SERVER = 1,
/**
* 3: The SDK has not received a response from the server in five seconds. The current timeout is set as
* five seconds.
*/
CHANNEL_MESSAGE_SENT_TIMEOUT = 3,
};
/**
* The join channel error.
*/
enum JOIN_CHANNEL_ERR {
/**
0: The method call succeeds, or the user joins the channel successfully.
*/
JOIN_CHANNEL_ERR_OK = 0,
/**
1: Common failure. The user fails to join the channel.
*/
JOIN_CHANNEL_ERR_FAILURE = 1,
/**
2: **RESERVED FOR FUTURE USE**
*/
JOIN_CHANNEL_ERR_REJECTED = 2, // Usually occurs when the user is already in the channel
/**
3: The user fails to join the channel because the argument is invalid.
*/
JOIN_CHANNEL_ERR_INVALID_ARGUMENT = 3,
/**
4: A timeout occurs when joining the channel. The current timeout is set as five seconds. Possible reasons: The user is in the \ref agora::rtm::CONNECTION_STATE_ABORTED "CONNECTION_STATE_ABORTED" state.
*/
JOIN_CHANNEL_TIMEOUT = 4,
/**
5: The number of the RTM channels you are in exceeds the limit of 20.
*/
JOIN_CHANNEL_ERR_EXCEED_LIMIT = 5,
/**
6: The user is joining or has joined the channel.
*/
JOIN_CHANNEL_ERR_ALREADY_JOINED = 6,
/**
7: The method call frequency exceeds 50 queries every three seconds.
*/
JOIN_CHANNEL_ERR_TOO_OFTEN = 7,
/**
8: The frequency of joining the same channel exceeds two times every five seconds.
*/
JOIN_CHANNEL_ERR_JOIN_SAME_CHANNEL_TOO_OFTEN = 8,
/**
101: \ref agora::rtm::IRtmService "IRtmService" is not initialized.
*/
JOIN_CHANNEL_ERR_NOT_INITIALIZED = 101,
/**
102: The user does not call the \ref agora::rtm::IRtmService::login "login" method, or the method call of \ref agora::rtm::IRtmService::login "login" does not succeed before joining the channel.
*/
JOIN_CHANNEL_ERR_USER_NOT_LOGGED_IN = 102,
};
/**
@brief Error codes related to leaving a channel.
*/
enum LEAVE_CHANNEL_ERR {
/**
0: The method call succeeds, or the user leaves the channel successfully.
*/
LEAVE_CHANNEL_ERR_OK = 0,
/**
1: Common failure. The user fails to leave the channel.
*/
LEAVE_CHANNEL_ERR_FAILURE = 1,
/**
2: **RESERVED FOR FUTURE USE**
*/
LEAVE_CHANNEL_ERR_REJECTED = 2,
/**
3: The user is not in the channel.
*/
LEAVE_CHANNEL_ERR_NOT_IN_CHANNEL = 3,
/**
101: \ref agora::rtm::IRtmService "IRtmService" is not initialized.
*/
LEAVE_CHANNEL_ERR_NOT_INITIALIZED = 101,
/**
102: The user does not call the \ref agora::rtm::IRtmService::login "login" method, or the method call of \ref agora::rtm::IRtmService::login "login" does not succeed before calling the \ref agora::rtm::IChannel::leave "leave" method.
*/
LEAVE_CHANNEL_ERR_USER_NOT_LOGGED_IN = 102,
};
/**
* The reason for a user to leave the channel.
*/
enum LEAVE_CHANNEL_REASON {
/**
* 1: The user quits the channel.
*/
LEAVE_CHANNEL_REASON_QUIT = 1,
/**
* 2: The user is kicked off the channel.
*/
LEAVE_CHANNEL_REASON_KICKED = 2,
};
/**
@brief Error codes related to sending a channel message.
*/
enum CHANNEL_MESSAGE_ERR_CODE {
/**
0: The method call succeeds, or the server receives the channel message.
*/
CHANNEL_MESSAGE_ERR_OK = 0,
/**
1: Common failure. The user fails to send the channel message.
*/
CHANNEL_MESSAGE_ERR_FAILURE = 1,
/**
2: The SDK does not receive a response from the server in 10 seconds. The current timeout is set as 10 seconds. Possible reasons: The user is in the \ref agora::rtm::CONNECTION_STATE_ABORTED "CONNECTION_STATE_ABORTED" state.
*/
CHANNEL_MESSAGE_ERR_SENT_TIMEOUT = 2,
/**
3: The method call frequency exceeds the limit of (RTM SDK for Windows C++) 180 calls every three seconds or (RTM SDK for Linux C++) 1500 calls every three seconds, with channel and peer messages taken together..
*/
CHANNEL_MESSAGE_ERR_TOO_OFTEN = 3,
/**
4: The message is null or exceeds 32 KB in length.
*/
CHANNEL_MESSAGE_ERR_INVALID_MESSAGE = 4,
/**
101: \ref agora::rtm::IRtmService "IRtmService" is not initialized.
*/
CHANNEL_MESSAGE_ERR_NOT_INITIALIZED = 101,
/**
102: The user does not call the \ref agora::rtm::IRtmService::login "login" method, or the method call of \ref agora::rtm::IRtmService::login "login" does not succeed before sending out a channel message.
*/
CHANNEL_MESSAGE_ERR_USER_NOT_LOGGED_IN = 102,
};
/**
* The response code.
*/
enum RESPONSE_CODE {
/**
* 1: The response
*/
RESPONSE_CODE_SUCCESS = 1,
RESPONSE_CODE_FAILURE = 2,
};
/**
* The message type.
*/
enum MESSAGE_TYPE {
/**
* 0: The message type is undefined.
*/
MESSAGE_TYPE_UNDEFINED = 0,
/**
* 1: A text message.
*/
MESSAGE_TYPE_TEXT = 1,
/**
* 2: A raw message in binary, for example, audio data, or video data.
*/
MESSAGE_TYPE_BINARY = 2,
/**
* 4: A converge message.
*/
MESSAGE_TYPE_CONVERGE = 4,
};
/**
* The IMessage class.
*/
class IMessage {
public:
/**
* Creates an IMessage instance.
*
* The created IMessage instance can be either for a channel message or for a peer-to-peer message.
*
* You can set the content of the text message later using the setText() method.
* @return
* - An empty text IMessage instance, if the method call succeeds.
*/
static IMessage *createMessage();
virtual ~IMessage() {}
/**
* Gets the ID of the message.
* @return The ID of the current IMessage instance.
*/
virtual int64_t getMessageId() const = 0;
/**
* Gets the message type.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getMessageType() const = 0;
/**
* Sets the content of the text message, or the text description of the raw message.
* @param str The content of the text message, or the text description of the raw message. The maximum length
* is 32 KB.
*/
virtual void setText(const char *str) = 0;
/**
* Gets the content of the text messsage, or the text description of the raw message.
* @return
* - The content of the text message or the text description of the raw message.
*/
virtual const char *getText() const = 0;
/**
* Get pointer of custom raw message
* @return
* - The content of binary raw message
*/
virtual const unsigned char *getRawMessageData() const = 0;
/**
* Get length of custom raw message
* @return
* - The length of binary raw message in bytes
*/
virtual int getRawMessageLength() const = 0;
/**
* Set message type
*/
virtual void setMessageType(int32_t type) = 0;
/**
* Set raw binary message
*/
virtual void setRawMessage(const uint8_t* data, int length) = 0;
/**
* Releases the IMessage instance.
*/
virtual void release() = 0;
};
/**
* The IChannelMember class.
*/
class IChannelMember {
public:
virtual ~IChannelMember() {}
/**
* Gets the ID of the channel member.
* @return The ID of the channel member.
*/
virtual const char *getMemberId() const = 0;
/**
* Gets the ID of the channel.
* @return The ID of the channel.
*/
virtual const char *getChannelId() const = 0;
/**
* Releases the IChannelMember class.
*/
virtual void release() = 0;
};
/**
* The IChannelAttributes class.
*/
class IChannelAttributes {
public:
/**
* Creates an IChannelAttributes instance.
* @return
* - An IChannelAttributes instance, if the method call succeeds.
*/
static IChannelAttributes *createChannelAttributes();
/**
* Adds an attribute to a specified channel.
*
* @param key The pointer to the attribute key.
* @param value The pointer to the attribute value.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int addAttribute(const char *key, const char *value) = 0;
/**
* Removes an attribute from the channel.
* @param key The pointer to the attribute key.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int removeAttribute(const char *key) = 0;
/**
* Gets the size of the attributes.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getAttributesSize() const = 0;
/**
* Gets the channel attributes.
* @param size The size of the channel attributes.
* @param key The pointer to the key of each channel attribute.
* @param value The pointer to the value of each channel attribute.
*/
virtual void getAttributes(int size, char **key,
char **value) const = 0; // todo: discussion, how to traveral
/**
* Gets the value of a channel attribute using the attribute key.
* @param key The pointer to the key of the channel attribute that you want to get.
*/
virtual const char *getAttributeValue(const char *key) const = 0;
/**
* Releases the IChannelAttributes instance.
* @param
* - 0: Success.
* - < 0: Failure.
*/
virtual int release() = 0;
};
/**
* The IChannelEventHandler class.
*/
class IChannelEventHandler {
public:
virtual ~IChannelEventHandler() {}
/**
* Occurs when the local user successfully joins a channel.
*/
virtual void onJoinSuccess() {}
/**
* Occurs when the local user fails to join a channel.
* @param errorCode The error code: #JOIN_CHANNEL_ERR.
*/
virtual void onJoinFailure(JOIN_CHANNEL_ERR errorCode) {}
/**
* Occurs when the local user leaves a channel.
* @param errorCode The error code. See #LEAVE_CHANNEL_ERR.
*/
virtual void onLeave(LEAVE_CHANNEL_ERR errorCode) {}
/**
* Occurs when the local user receives a channel message.
* @param message The pointer to the messsage: IMessage.
*/
virtual void onMessageReceived(const char *userId, const IMessage *message) {}
/**
* Reports the state of the message sent by the local user.
* @param messageId ID of the message.
* @param state The state of the message: #CHANNEL_MESSAGE_STATE.
*/
virtual void onSendMessageState(int64_t messageId, CHANNEL_MESSAGE_STATE state) {}
/**
Returns the result of the \ref agora::rtm::IChannel::sendMessage "sendMessage" method call.
@param messageId The ID of the sent channel message.
@param state The error codes. See #CHANNEL_MESSAGE_ERR_CODE.
*/
virtual void onSendMessageResult(long long messageId, CHANNEL_MESSAGE_ERR_CODE state) {}
/**
* Occurs when another member joins the channel.
* @param member The pointer to the member who joins the channel: IChannelMember.
*/
virtual void onMemberJoined(IChannelMember *member) {}
/**
* Occurs when the other member leaves the channel.
* @param member The pointer to the member who leaves the channel: IChannelMember.
*/
virtual void onMemberLeft(IChannelMember *member) {}
/**
* Reports all the members in the channel.
* @param members The pointer to each member in the channel: IChannelMember.
* @param userCount The number of users in the channel.
*/
virtual void onMembersGotten(IChannelMember **members, int userCount) {}
/**
* Occurs when the channel attributes are updated.
* @param attributes The pointer to the current channel attributes: IChannelAttributes.
*/
virtual void onAttributesUpdated(const IChannelAttributes *attributes) {}
/**
* Occurs when the local user calls updateAttributes().
* @param requestId ID of the current attribute update request.
* @param resCode The response code: #RESPONSE_CODE.
*/
virtual void onUpdateAttributesResponse(int64_t requestId, RESPONSE_CODE resCode) {}
/**
* Occurs when the channel attributes are deleted.
* @param attributes The pointer to the channel attributes that you want to remove: IChannelAttributes.
*/
virtual void onAttributesDeleted(const IChannelAttributes *attributes) {}
/**
* Occurs when the local user calls deleteAttributes().
* @param requestId ID of the current attribute delete request.
* @param resCode The response code: #RESPONSE_CODE.
*/
virtual void onDeleteAttributesResponse(int64_t requestId, RESPONSE_CODE resCode) {}
};
/**
* The IChannel class.
*/
class IChannel {
public:
/**
* Sets an event handler for IChannel.
* @param eventHandler The pointer to the event handler of IChannel: IChannelEventHandler.
*/
virtual int setEventHandler(IChannelEventHandler *eventHandler, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Joins the current channel.
*
* A successful method call triggers either onJoinSuccess() or onJoinFailure() on the local client, to report
* the state of joining the channel.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int join(aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Leaves the current channel.
*
* After the local user successfully leaves the channel, the SDK triggers the onLeave() on the local client.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int leave(aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Sends a channel message.
*
* After you successfully send a channel message, all members in the channel receive the message in the
* onMessageReceived() callback.
* @param message The pointer to the channel message that you want to send: IMessage.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int sendMessage(const IMessage *message, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Updates the channel attributes.
*
* A successful method call triggers the onUpdateAttributesResponse() callback on the local client.
* @param attributes The pointer to the channel attributes that you want to update: IChannelAttributes.
* @param requestId ID of the current update request.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int updateAttributes(IChannelAttributes *attributes, int64_t &requestId, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Removes the channel attributes.
*
* A successful method call triggers the onDeleteAttributesResponse() callback on the local client.
* @param attributes The pointer to the channel attributes that you want to remove: IChannelAttributes.
* @param requestId ID of the current delete request.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int deleteAttributes(IChannelAttributes *attributes, int64_t &requestId, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Gets the current request ID.
* @return
* - The pointer to the request ID, if the method call succeeds.
* - An empty pointer NULL, if the method call fails.
*/
virtual const char *getId() const = 0;
// sync_call
/**
* Releases the IChannel instance.
*
* This is a synchronous method call, which means that the SDK reports the result of this method call
* after the IChannel instance is successfully released.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int release() = 0;
};
/**
* The IRtmServiceEventHandler class.
*/
class IRtmServiceEventHandler {
public:
virtual ~IRtmServiceEventHandler() {}
/**
* Occurs when the user successfully logs in the RTM service.
*/
virtual void onLoginSuccess() {}
/**
* Occurs when the user fails to log in the RTM service.
* @param errorCode The reason for the login failure: #LOGIN_ERR_CODE.
*/
virtual void onLoginFailure(LOGIN_ERR_CODE errorCode) {}
/**
* Occurs when the user successfully logs out of the RTM service.
*/
virtual void onLogout() {}
/**
* Occurs when the connection state of the local user has changed.
* @param state The current connection state: #CONNECTION_STATE.
*/
virtual void onConnectionStateChanged(CONNECTION_STATE state) {}
/**
* Reports the state of sending a message.
* @param messageId ID of the message.
* @param state The current state of the message: #PEER_MESSAGE_STATE.
*/
virtual void onSendMessageState(int64_t messageId, PEER_MESSAGE_STATE state) {}
/**
* Occurs when the local user receives a message from a remote user.
* @param peerId ID of the remote user that sends the message.
* @param message The pointer to the message: IMessage.
*/
virtual void onMessageReceivedFromPeer(const char *peerId, const IMessage *message) {}
};
/**
* The IRtmService class.
*/
class IRtmService {
public:
virtual ~IRtmService() {}
/**
* Creates and gets an IRtmService instance.
* @param appId The pointer to the app ID.
* @param eventHandler The pointer to the IRtmServiceEventHandler object.
* @param eventSpace The connection specific ID, used during report to argus.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int initialize(const char *appId, IRtmServiceEventHandler *eventHandler) = 0;
/**
* Releases the IRtmServiceEventHandler object.
* @param eventHandler The pointer to the IRtmServiceEventHandler object.
*/
virtual void unregisterObserver(IRtmServiceEventHandler *eventHandler) = 0;
/**
* Releases the IRtmService instance.
* @param sync Determines whether to report the result of this method call synchronously.
* - true: Report the result of this method call after the IRtmService instance is released.
* - false: (Default) Report the result of this method call immediately, even when the IRtmService is not
* released.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int release(bool sync = false) = 0;
/**
* Logs in the RTM service.
*
* @note
* - If you login with the same user ID from a different instance, your previous login will be kicked.
* - The call frequency limit of this method is 2 queries per second.
* @param token The token used to log in the RTM service.
* @param userId ID of the user logging in the RTM service.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int login(const char *token, const char *userId, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Logs out of the RTM service.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int logout(aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Sends a peer message to a specified remote user.
*
* @param peerId The pointer to the ID of the remote user.
* @param message The pointer to message: IMessage.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int sendMessageToPeer(const char *peerId, const IMessage *message, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Creates an RTM channel.
*
* @param channelId The unique channel name for an RTM session. Supported character scopes are:
* - All lowercase English letters: a to z.
* - All uppercase English letters: A to Z.
* - All numeric characters: 0 to 9.
* - The space character.
* - Punctuation characters and other symbols, including: "!", "#", "$", "%", "&", "(", ")", "+", "-", ":", ";", "<", "=",
* ".", ">", "?", "@", "[", "]", "^", "_", " {", "}", "|", "~", ","
*
* @param eventHandler The pointer to IChannelEventHandler.
* @return
* - The pointer to an IChannel instance, if the method call succeeds.
* - An empty pointer NULL, if the method call fails.
*/
virtual IChannel *createChannel(const char *channelId, IChannelEventHandler *eventHandler) = 0;
};
} // namespace rtm
} // namespace agora

View File

@@ -0,0 +1,193 @@
// Copyright (c) 2019 Agora.io. All rights reserved
// This program is confidential and proprietary to Agora.io.
// And may not be copied, reproduced, modified, disclosed to others, published
// or used, in whole or in part, without the express prior written permission
// of Agora.io.
#pragma once // NOLINT(build/header_guard)
#include "AgoraBase.h"
#include "AgoraRefPtr.h"
#include "IAgoraService.h"
#include "NGIAgoraRtcConnection.h"
#include <aosl/api/cpp/aosl_ares_class.h>
namespace agora {
namespace rtc {
/**
* The events in the RTMP channel.
*/
enum RTMP_CHANNEL_EVENT
{
/**
* 0: The live stream service is disconnected.
*/
RTMP_CHANNEL_EVENT_DISCONNECT = 0,
/**
* 1: The live stream service has left the channel.
*/
RTMP_CHANNEL_EVENT_LEAVE_CHANNEL = 1,
/**
* 2: The live stream service is banned by the server.
*/
RTMP_CHANNEL_EVENT_BANNED_BY_SERVER = 2
};
/**
* The IRtmpStreamingObserver class, which monitors events in of the live streaming service.
*/
class IRtmpStreamingObserver {
public:
/**
* Occurs when the state of the RTMP streaming changes.
*
* The SDK triggers this callback to report the result of the local user calling
* `addPublishStreamUrl` or `removePublishStreamUrl`.
*
* This callback also reports the streaming URL and its current streaming state. When exceptions
* occur, you can troubleshoot issues by referring to the detailed error description in the `errCode`
* parameter.
*
* @param url The RTMP URL address.
* @param state The RTMP streaming state: #RTMP_STREAM_PUBLISH_STATE.
* @param reason The detailed error information for streaming: #RTMP_STREAM_PUBLISH_REASON.
*/
virtual void onRtmpStreamingStateChanged(const char* url, RTMP_STREAM_PUBLISH_STATE state,
RTMP_STREAM_PUBLISH_REASON reason) {
(void)url;
(void)state;
(void)reason;
}
/** Reports events during the RTMP or RTMPS streaming.
*
* @since v3.1.0
*
* @param url The RTMP or RTMPS streaming URL.
* @param eventCode The event code. See #RTMP_STREAMING_EVENT
*/
virtual void onRtmpStreamingEvent(const char* url, RTMP_STREAMING_EVENT eventCode) {
(void)url;
(void)eventCode;
}
/**
* Occurs when the publisher's transcoding settings are updated.
*
* When the `LiveTranscoding` class in the `setLiveTransocding` method updates, the SDK triggers this callback
* to report the update information.
*
* @note
* If you call the `setLiveTranscoding` method to set the `LiveTranscoding` class for the first time, the SDK
* does not trigger this callback.
*/
virtual void onTranscodingUpdated() {}
};
/**
* The IRtmpStreamingService class, which enables the live stream service.
*/
class IRtmpStreamingService : public RefCountInterface {
public:
/** Publishes the local stream without transcoding to a specified CDN live RTMP address. (CDN live only.)
* The SDK returns the result of this method call in the \ref IRtcEngineEventHandler::onStreamPublished "onStreamPublished" callback.
* The \ref agora::rtc::IRtcEngine::startRtmpStreamWithoutTranscoding "startRtmpStreamWithoutTranscoding" method call triggers the \ref agora::rtc::IRtcEngineEventHandler::onRtmpStreamingStateChanged "onRtmpStreamingStateChanged" callback on the local client to report the state of adding a local stream to the CDN.
* @note
* - Ensure that the user joins the channel before calling this method.
* - This method adds only one stream RTMP URL address each time it is called.
* - The RTMP URL address must not contain special characters, such as Chinese language characters.
* - This method applies to Live Broadcast only.
* @param url The CDN streaming URL in the RTMP format. The maximum length of this parameter is 1024 bytes.
* @return
* - 0: Success.
* - < 0: Failure.
* - #ERR_INVALID_ARGUMENT (2): The RTMP URL address is NULL or has a string length of 0.
* - #ERR_NOT_INITIALIZED (7): You have not initialized the RTC engine when publishing the stream.
* - #ERR_ALREADY_IN_USE (19): This streaming URL is already in use. Use a new streaming URL for CDN streaming.
*/
virtual int startRtmpStreamWithoutTranscoding(const char* url, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/** Publishes the local stream with transcoding to a specified CDN live RTMP address. (CDN live only.)
* The SDK returns the result of this method call in the \ref IRtcEngineEventHandler::onStreamPublished "onStreamPublished" callback.
* The \ref agora::rtc::IRtcEngine::startRtmpStreamWithTranscoding "startRtmpStreamWithTranscoding" method call triggers the \ref agora::rtc::IRtcEngineEventHandler::onRtmpStreamingStateChanged "onRtmpStreamingStateChanged" callback on the local client to report the state of adding a local stream to the CDN.
* @note
* - Ensure that the user joins the channel before calling this method.
* - This method adds only one stream RTMP URL address each time it is called.
* - The RTMP URL address must not contain special characters, such as Chinese language characters.
* - This method applies to Live Broadcast only.
* @param url The CDN streaming URL in the RTMP format. The maximum length of this parameter is 1024 bytes.
* @param transcoding Sets the CDN live audio/video transcoding settings. See LiveTranscoding.
* @return
* - 0: Success.
* - < 0: Failure.
* - #ERR_INVALID_ARGUMENT (2): The RTMP URL address is NULL or has a string length of 0.
* - #ERR_NOT_INITIALIZED (7): You have not initialized the RTC engine when publishing the stream.
* - #ERR_ALREADY_IN_USE (19): This streaming URL is already in use. Use a new streaming URL for CDN streaming.
*/
virtual int startRtmpStreamWithTranscoding(const char* url, const LiveTranscoding& transcoding, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/** Update the video layout and audio settings for CDN live. (CDN live only.)
* @note This method applies to Live Broadcast only.
* @param transcoding Sets the CDN live audio/video transcoding settings. See LiveTranscoding.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int updateRtmpTranscoding(const LiveTranscoding& transcoding, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/** Stop an RTMP stream with transcoding or without transcoding from the CDN. (CDN live only.)
* This method removes the RTMP URL address (added by the \ref IRtcEngine::startRtmpStreamWithoutTranscoding "startRtmpStreamWithoutTranscoding" method
* or IRtcEngine::startRtmpStreamWithTranscoding "startRtmpStreamWithTranscoding" method) from a CDN live stream.
* The SDK returns the result of this method call in the \ref IRtcEngineEventHandler::onStreamUnpublished "onStreamUnpublished" callback.
* The \ref agora::rtc::IRtcEngine::stopRtmpStream "stopRtmpStream" method call triggers the \ref agora::rtc::IRtcEngineEventHandler::onRtmpStreamingStateChanged "onRtmpStreamingStateChanged" callback on the local client to report the state of removing an RTMP stream from the CDN.
* @note
* - This method removes only one RTMP URL address each time it is called.
* - The RTMP URL address must not contain special characters, such as Chinese language characters.
* - This method applies to Live Broadcast only.
* @param url The RTMP URL address to be removed. The maximum length of this parameter is 1024 bytes.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int stopRtmpStream(const char* url, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Registers an RTMP streaming observer.
* @param observer The pointer to an RTMP streaming observer. See \ref agora::rtc::IRtmpStreamingObserver "IRtmpStreamingObserver".
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int registerObserver(IRtmpStreamingObserver* observer, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Releases the RTMP streaming observer created by registerObserver().
* @param observer The pointer to the RTMP streaming observer that you want to release. See \ref agora::rtc::IRtmpStreamingObserver "IRtmpStreamingObserver".
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int unregisterObserver(IRtmpStreamingObserver* observer) = 0;
protected:
~IRtmpStreamingService() {}
};
} // namespace rtc
} // namespace agora

View File

@@ -0,0 +1,302 @@
//
// AgoraRtcEngine SDK
//
// Copyright (c) 2019 Agora.io. All rights reserved.
//
#pragma once
#include <stdint.h>
#include "AgoraBase.h"
#include "AgoraMediaBase.h"
#include "AgoraRefPtr.h"
#include "IAgoraRtcEngineEx.h"
namespace agora {
namespace rtc {
// The information of remote voice position
struct RemoteVoicePositionInfo {
// The coordnate of remote voice source, (x, y, z)
float position[3];
// The forward vector of remote voice, (x, y, z). When it's not set, the vector is forward to listner.
float forward[3];
};
struct SpatialAudioZone {
//the zone id
int zoneSetId;
//zone center point
float position[3];
//forward direction
float forward[3];
//right direction
float right[3];
//up direction
float up[3];
//the forward side length of the zone
float forwardLength;
//tehe right side length of the zone
float rightLength;
//the up side length of the zone
float upLength;
//the audio attenuation of zone
float audioAttenuation;
};
/** The definition of LocalSpatialAudioConfig
*/
struct LocalSpatialAudioConfig {
/*The reference to \ref IRtcEngine, which is the base interface class of the Agora RTC SDK and provides
* the real-time audio and video communication functionality.
*/
agora::rtc::IRtcEngine* rtcEngine;
LocalSpatialAudioConfig() : rtcEngine(NULL) {}
};
/** The IBaseSpatialAudioEngine class provides the common methods of ICloudSpatialAudioEngine and ILocalSpatialAudioEngine.
*/
class ILocalSpatialAudioEngine: public RefCountInterface {
protected:
virtual ~ILocalSpatialAudioEngine() {}
public:
/**
* Releases all the resources occupied by spatial audio engine.
*/
virtual void release() = 0;
/**
* Initializes the ILocalSpatialAudioEngine object and allocates the internal resources.
*
* @note Ensure that you call IRtcEngine::queryInterface and initialize before calling any other ILocalSpatialAudioEngine APIs.
*
* @param config The pointer to the LocalSpatialAudioConfig. See #LocalSpatialAudioConfig.
*
* @return
* - 0: Success.
* - <0: Failure.
*/
virtual int initialize(const LocalSpatialAudioConfig& config) = 0;
/**
* Updates the position information of remote user. You should call it when remote user whose role is broadcaster moves.
*
* @param uid The remote user ID. It should be the same as RTC channel remote user id.
* @param posInfo The position information of remote user. See #RemoteVoicePositionInfo.
* @return
* - 0: Success.
* - <0: Failure.
*/
virtual int updateRemotePosition(uid_t uid, const RemoteVoicePositionInfo &posInfo) = 0;
/**
* Updates the position of remote user. It's supposed to use with IRtcEngineEx::joinChannelEx.
*
* @param uid The remote user ID. It should be the same as RTC channel remote user id.
* @param posInfo The position information of remote user. See #RemoteVoicePositionInfo.
* @param connection The RTC connection whose spatial audio effect you want to update. See #RtcConnection.
* @return
* - 0: Success.
* - <0: Failure.
*/
virtual int updateRemotePositionEx(uid_t uid, const RemoteVoicePositionInfo &posInfo, const RtcConnection& connection) = 0;
/**
* Remove the position information of remote user. You should call it when remote user called IRtcEngine::leaveChannel.
*
* @param uid The remote user ID. It should be the same as RTC channel remote user id.
* @return
* - 0: Success.
* - <0: Failure.
*/
virtual int removeRemotePosition(uid_t uid) = 0;
/**
* Remove the position information of remote user. It's supposed to use with IRtcEngineEx::joinChannelEx.
*
* @param uid The remote user ID. It should be the same as RTC channel remote user id.
* @param connection The RTC connection whose spatial audio effect you want to update. See #RtcConnection.
* @return
* - 0: Success.
* - <0: Failure.
*/
virtual int removeRemotePositionEx(uid_t uid, const RtcConnection& connection) = 0;
/**
* Clear the position informations of remote users. It's supposed to use with IRtcEngineEx::joinChannelEx.
*
* @return
* - 0: Success.
* - <0: Failure.
*/
virtual int clearRemotePositionsEx(const RtcConnection& connection) = 0;
/**
* Updates the position of local user. This method is used in scene with multi RtcConnection.
*
* @note
* - This method is only effective in ILocalSpatialAudioEngine currently.
*
* @param position The sound position of the user. The coordinate order is forward, right, and up.
* @param axisForward The vector in the direction of the forward axis in the coordinate system.
* @param axisRight The vector in the direction of the right axis in the coordinate system.
* @param axisUp The vector in the direction of the up axis in the coordinate system.
* @param connection The RTC connection whose spatial audio effect you want to update.
* @return
* - 0: Success.
* - <0: Failure.
*/
virtual int updateSelfPositionEx(const float position[3], const float axisForward[3], const float axisRight[3], const float axisUp[3], const RtcConnection& connection) = 0;
/**
* This method sets the maximum number of streams that a player can receive in a
* specified audio reception range.
*
* @note You can call this method either before or after calling enterRoom:
* - Calling this method before enterRoom affects the maximum number of received streams
* the next time the player enters a room.
* - Calling this method after entering a room changes the current maximum number of
* received streams of the player.
*
* @param maxCount The maximum number of streams that a player can receive within
* a specified audio reception range. If the number of receivable streams exceeds
* the set value, the SDK receives the set number of streams closest to the player.
*
* @return
* - 0: Success.
* - <0: Failure.
*/
virtual int setMaxAudioRecvCount(int maxCount) = 0;
/**
* This method sets the audio reception range. The unit of the audio reception range
* is the same as the unit of distance in the game engine.
*
* @note You can call this method either before or after calling enterRoom.
* During the game, you can call it multiple times to update the audio reception range.
*
* @param range The maximum audio reception range, in the unit of game engine distance.
*
* @return
* - 0: Success.
* - <0: Failure.
*/
virtual int setAudioRecvRange(float range) = 0;
/**
* This method sets distance unit of game engine. The smaller the unit is, the sound fades slower
* with distance.
*
* @note You can call this method either before or after calling enterRoom.
* During the game, you can call it multiple times to update the distance unit.
*
* @param unit The number of meters that the game engine distance per unit is equal to. For example, setting unit as 2 means the game engine distance per unit equals 2 meters.
*
* @return
* - 0: Success.
* - <0: Failure.
*/
virtual int setDistanceUnit(float unit) = 0;
/**
* Updates the position of local user.
* When calling it in ICloudSpatialAudioEngine, it triggers the SDK to update the user position to the Agora spatial audio server. The Agora spatial audio server uses the users' world coordinates and audio reception range to determine whether they are within each other's specified audio reception range.
* When calling it in ILocalSpatialAudioEngine, it triggers the SDK to calculate the relative position between the local and remote users and updates spatial audio parameters.
*
* when calling it in ICloudSpatialAudioEngine, you should notice:
* @note
* - Call the method after calling enterRoom.
* - The call frequency is determined by the app. Agora recommends calling this method every
* 120 to 7000 ms. Otherwise, the SDK may lose synchronization with the server.
*
* @param position The sound position of the user. The coordinate order is forward, right, and up.
* @param axisForward The vector in the direction of the forward axis in the coordinate system.
* @param axisRight The vector in the direction of the right axis in the coordinate system.
* @param axisUp The vector in the direction of the up axis in the coordinate system.
* @return
* - 0: Success.
* - <0: Failure.
*/
virtual int updateSelfPosition(const float position[3], const float axisForward[3], const float axisRight[3], const float axisUp[3]) = 0;
/**
* Updates the position of a media player in scene. This method has same behavior both in ICloudSpatialAudioEngine and ILocalSpatialAudioEngine.
*
* @note
* - This method is suggested to be called once if you don't move media player in the virtual space.
*
* @param playerId The ID of the media player. You can get it by IMediaPlayer::getMediaPlayerId.
* @param positionInfo The position information of media player in the virtual space. For details inforamtion, see the declaration of RemoteVoicePositionInfo.
* @return
* - 0: Success.
* - <0: Failure.
*/
virtual int updatePlayerPositionInfo(int playerId, const RemoteVoicePositionInfo& positionInfo) = 0;
/**
* Set parameters for spatial audio engine. It's deprecated for using.
*
* @param params The parameter string.
* @return
* - 0: Success.
* - <0: Failure.
*/
virtual int setParameters(const char* params) = 0;
/**
* Mute or unmute local audio stream.
*
* @param mute When it's false, it will send local audio stream, otherwise it will not send local audio stream.
* @return
* - 0: Success.
* - <0: Failure.
*/
virtual int muteLocalAudioStream(bool mute) = 0;
/**
* Mute all remote audio streams. It determines wether SDK receves remote audio streams or not.
*
* @param mute When it's false, SDK will receive remote audio streams, otherwise SDK will not receive remote audio streams.
* @return
* - 0: Success.
* - <0: Failure.
*/
virtual int muteAllRemoteAudioStreams(bool mute) = 0;
/**
* Mute or unmute remote user audio stream.
*
* @param uid The ID of the remote user.
* @param mute When it's false, SDK will receive remote user audio streams, otherwise SDK will not receive remote user audio streams.
* @return
* - 0: Success.
* - <0: Failure.
*/
virtual int muteRemoteAudioStream(uid_t uid, bool mute) = 0;
virtual int setRemoteAudioAttenuation(uid_t uid, double attenuation, bool forceSet) = 0;
/**
* Setting up sound Space
*
* @param zones The Sound space array
* @param zoneCount the sound Space count of array
* @return
* - 0: Success.
* - <0: Failure.
*/
virtual int setZones(const SpatialAudioZone *zones, unsigned int zoneCount) = 0;
/**
* Set the audio attenuation coefficient of the player
* @param playerId The ID of the media player. You can get it by IMediaPlayer::getMediaPlayerId.
* @param attenuation The audio attenuation of the media player.
* @param forceSet Whether to force the setting of audio attenuation coefficient.
* @return
* - 0: Success.
* - <0: Failure.
*/
virtual int setPlayerAttenuation(int playerId, double attenuation, bool forceSet) = 0;
/**
* Clear the position informations of remote users.
*
* @return
* - 0: Success.
* - <0: Failure.
*/
virtual int clearRemotePositions() = 0;
};
} // namespace rtc
} // namespace agora

View File

@@ -0,0 +1,532 @@
//
// Agora SDK
//
// Copyright (c) 2021 Agora.io. All rights reserved.
//
#pragma once // NOLINT(build/header_guard)
namespace agora {
namespace rtc {
/**
* The maximum device ID length.
*/
enum MAX_DEVICE_ID_LENGTH_TYPE {
/**
* The maximum device ID length is 512.
*/
MAX_DEVICE_ID_LENGTH = 512
};
/**
* The IAudioDeviceCollection class.
*/
class IAudioDeviceCollection {
public:
virtual ~IAudioDeviceCollection() {}
/**
* Gets the total number of the playback or recording devices.
*
* Call \ref IAudioDeviceManager::enumeratePlaybackDevices
* "enumeratePlaybackDevices" first, and then call this method to return the
* number of the audio playback devices.
*
* @return
* - The number of the audio devices, if the method call succeeds.
* - < 0, if the method call fails.
*/
virtual int getCount() = 0;
/**
* Gets the information of a specified audio device.
* @param index An input parameter that specifies the audio device.
* @param deviceName An output parameter that indicates the device name.
* @param deviceId An output parameter that indicates the device ID.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getDevice(int index, char deviceName[MAX_DEVICE_ID_LENGTH],
char deviceId[MAX_DEVICE_ID_LENGTH]) = 0;
/**
* Gets the information of a specified audio device.
* @note
* @param index An input parameter that specifies the audio device.
* @param deviceName An output parameter that indicates the device name.
* @param deviceTypeName An output parameter that indicates the device type name. such as Built-in, USB, HDMI, etc. (MacOS only)
* @param deviceId An output parameter that indicates the device ID.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getDevice(int index, char deviceName[MAX_DEVICE_ID_LENGTH], char deviceTypeName[MAX_DEVICE_ID_LENGTH],
char deviceId[MAX_DEVICE_ID_LENGTH]) = 0;
/**
* Specifies a device with the device ID.
* @param deviceId The device ID.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setDevice(const char deviceId[MAX_DEVICE_ID_LENGTH]) = 0;
/**
* Gets the default audio device of the system (for macOS and Windows only).
*
* @param deviceName The name of the system default audio device.
* @param deviceId The device ID of the the system default audio device.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getDefaultDevice(char deviceName[MAX_DEVICE_ID_LENGTH], char deviceId[MAX_DEVICE_ID_LENGTH]) = 0;
/**
* Gets the default audio device of the system (for macOS and Windows only).
*
* @param deviceName The name of the system default audio device.
* @param deviceTypeName The device type name of the the system default audio device, such as Built-in, USB, HDMI, etc. (MacOS only)
* @param deviceId The device ID of the the system default audio device.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getDefaultDevice(char deviceName[MAX_DEVICE_ID_LENGTH], char deviceTypeName[MAX_DEVICE_ID_LENGTH], char deviceId[MAX_DEVICE_ID_LENGTH]) = 0;
/**
* Sets the volume of the app.
*
* @param volume The volume of the app. The value range is [0, 255].
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setApplicationVolume(int volume) = 0;
/**
* Gets the volume of the app.
*
* @param volume The volume of the app. The value range is [0, 255]
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getApplicationVolume(int &volume) = 0;
/** Mutes or unmutes the app.
*
* @param mute Determines whether to mute the app:
* - true: Mute the app.
* - false: Unmute the app.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setApplicationMute(bool mute) = 0;
/**
* Gets the mute state of the app.
*
* @param mute A reference to the mute state of the app:
* - true: The app is muted.
* - false: The app is not muted.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int isApplicationMute(bool &mute) = 0;
/**
* Releases all IAudioDeviceCollection resources.
*/
virtual void release() = 0;
};
/**
* The IAudioDeviceManager class.
*/
class IAudioDeviceManager : public RefCountInterface {
public:
virtual ~IAudioDeviceManager() {}
/**
* Enumerates the audio playback devices.
*
* This method returns an IAudioDeviceCollection object that includes all the
* audio playback devices in the system. With the IAudioDeviceCollection
* object, the app can enumerate the audio playback devices. The app must call
* the \ref IAudioDeviceCollection::release "IAudioDeviceCollection::release"
* method to release the returned object after using it.
*
* @return
* - A pointer to the IAudioDeviceCollection object that includes all the
* audio playback devices in the system, if the method call succeeds.
* - The empty pointer NULL, if the method call fails.
*/
virtual IAudioDeviceCollection *enumeratePlaybackDevices() = 0;
/**
* Enumerates the audio recording devices.
*
* This method returns an IAudioDeviceCollection object that includes all the
* audio recording devices in the system. With the IAudioDeviceCollection
* object, the app can enumerate the audio recording devices. The app needs to
* call the \ref IAudioDeviceCollection::release
* "IAudioDeviceCollection::release" method to release the returned object
* after using it.
*
* @return
* - A pointer to the IAudioDeviceCollection object that includes all the
* audio recording devices in the system, if the method call succeeds.
* - The empty pointer NULL, if the method call fails.
*/
virtual IAudioDeviceCollection *enumerateRecordingDevices() = 0;
/**
* Specifies an audio playback device with the device ID.
*
* @param deviceId ID of the audio playback device. It can be retrieved by the
* \ref enumeratePlaybackDevices "enumeratePlaybackDevices" method. Plugging
* or unplugging the audio device does not change the device ID.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setPlaybackDevice(const char deviceId[MAX_DEVICE_ID_LENGTH]) = 0;
/**
* Gets the ID of the audio playback device.
* @param deviceId An output parameter that specifies the ID of the audio
* playback device.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getPlaybackDevice(char deviceId[MAX_DEVICE_ID_LENGTH]) = 0;
/**
* Gets the device ID and device name of the audio playback device.
* @param deviceId An output parameter that specifies the ID of the audio
* playback device.
* @param deviceName An output parameter that specifies the name of the audio
* playback device.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getPlaybackDeviceInfo(char deviceId[MAX_DEVICE_ID_LENGTH],
char deviceName[MAX_DEVICE_ID_LENGTH]) = 0;
/**
* Gets the device ID and device name and device type name of the audio playback device.
* @param deviceId An output parameter that specifies the ID of the audio playback device.
* @param deviceName An output parameter that specifies the name of the audio playback device.
* @param deviceTypeName An output parameter that specifies the device type name. such as Built-in, USB, HDMI, etc. (MacOS only)
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getPlaybackDeviceInfo(char deviceId[MAX_DEVICE_ID_LENGTH], char deviceName[MAX_DEVICE_ID_LENGTH], char deviceTypeName[MAX_DEVICE_ID_LENGTH]) = 0;
/**
* Sets the volume of the audio playback device.
* @param volume The volume of the audio playing device. The value range is
* [0, 255].
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setPlaybackDeviceVolume(int volume) = 0;
/**
* Gets the volume of the audio playback device.
* @param volume The volume of the audio playback device. The value range is
* [0, 255].
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getPlaybackDeviceVolume(int *volume) = 0;
/**
* Specifies an audio recording device with the device ID.
*
* @param deviceId ID of the audio recording device. It can be retrieved by
* the \ref enumerateRecordingDevices "enumerateRecordingDevices" method.
* Plugging or unplugging the audio device does not change the device ID.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setRecordingDevice(const char deviceId[MAX_DEVICE_ID_LENGTH]) = 0;
/**
* Gets the audio recording device by the device ID.
*
* @param deviceId ID of the audio recording device.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getRecordingDevice(char deviceId[MAX_DEVICE_ID_LENGTH]) = 0;
/**
* Gets the information of the audio recording device by the device ID and
* device name.
*
* @param deviceId ID of the audio recording device.
* @param deviceName The name of the audio recording device.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getRecordingDeviceInfo(char deviceId[MAX_DEVICE_ID_LENGTH],
char deviceName[MAX_DEVICE_ID_LENGTH]) = 0;
/**
* Gets the device ID and device name and device type name of the audio recording device.
*
* @param deviceId An output parameter that indicates the device id.
* @param deviceName An output parameter that indicates the device name.
* @param deviceTypeName An output parameter that indicates the device type name. such as Built-in, USB, HDMI, etc. (MacOS only)
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getRecordingDeviceInfo(char deviceId[MAX_DEVICE_ID_LENGTH], char deviceName[MAX_DEVICE_ID_LENGTH], char deviceTypeName[MAX_DEVICE_ID_LENGTH]) = 0;
/**
* Sets the volume of the recording device.
* @param volume The volume of the recording device. The value range is [0,
* 255].
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setRecordingDeviceVolume(int volume) = 0;
/**
* Gets the volume of the recording device.
* @param volume The volume of the microphone, ranging from 0 to 255.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getRecordingDeviceVolume(int *volume) = 0;
/**
* Specifies an audio loopback recording device with the device ID.
*
* @param deviceId ID of the audio loopback recording device. It can be retrieved by
* the \ref enumeratePlaybackDevices "enumeratePlaybackDevices" method.
* Plugging or unplugging the audio device does not change the device ID.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setLoopbackDevice(const char deviceId[MAX_DEVICE_ID_LENGTH]) = 0;
/**
* Gets the audio loopback recording device by the device ID.
*
* @param deviceId ID of the audio loopback recording device.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getLoopbackDevice(char deviceId[MAX_DEVICE_ID_LENGTH]) = 0;
/**
* Mutes or unmutes the audio playback device.
*
* @param mute Determines whether to mute the audio playback device.
* - true: Mute the device.
* - false: Unmute the device.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setPlaybackDeviceMute(bool mute) = 0;
/**
* Gets the mute state of the playback device.
*
* @param mute A pointer to the mute state of the playback device.
* - true: The playback device is muted.
* - false: The playback device is unmuted.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getPlaybackDeviceMute(bool *mute) = 0;
/**
* Mutes or unmutes the audio recording device.
*
* @param mute Determines whether to mute the recording device.
* - true: Mute the microphone.
* - false: Unmute the microphone.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setRecordingDeviceMute(bool mute) = 0;
/**
* Gets the mute state of the audio recording device.
*
* @param mute A pointer to the mute state of the recording device.
* - true: The microphone is muted.
* - false: The microphone is unmuted.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getRecordingDeviceMute(bool *mute) = 0;
/**
* Starts the audio playback device test.
*
* This method tests if the playback device works properly. In the test, the
* SDK plays an audio file specified by the user. If the user hears the audio,
* the playback device works properly.
*
* @param testAudioFilePath The file path of the audio file for the test,
* which is an absolute path in UTF8:
* - Supported file format: wav, mp3, m4a, and aac.
* - Supported file sampling rate: 8000, 16000, 32000, 44100, and 48000.
*
* @return
* - 0, if the method call succeeds and you can hear the sound of the
* specified audio file.
* - An error code, if the method call fails.
*/
virtual int startPlaybackDeviceTest(const char *testAudioFilePath) = 0;
/**
* Stops the audio playback device test.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int stopPlaybackDeviceTest() = 0;
/**
* Starts the recording device test.
*
* This method tests whether the recording device works properly. Once the
* test starts, the SDK uses the \ref
* IRtcEngineEventHandler::onAudioVolumeIndication "onAudioVolumeIndication"
* callback to notify the app on the volume information.
*
* @param indicationInterval The time interval (ms) between which the SDK
* triggers the `onAudioVolumeIndication` callback.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int startRecordingDeviceTest(int indicationInterval) = 0;
/**
* Stops the recording device test.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int stopRecordingDeviceTest() = 0;
/**
* Starts the audio device loopback test.
*
* This method tests whether the local audio devices are working properly.
* After calling this method, the microphone captures the local audio and
* plays it through the speaker, and the \ref
* IRtcEngineEventHandler::onAudioVolumeIndication "onAudioVolumeIndication"
* callback returns the local audio volume information at the set interval.
*
* @note This method tests the local audio devices and does not report the
* network conditions.
* @param indicationInterval The time interval (ms) at which the \ref
* IRtcEngineEventHandler::onAudioVolumeIndication "onAudioVolumeIndication"
* callback returns.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int startAudioDeviceLoopbackTest(int indicationInterval) = 0;
/**
* Stops the audio device loopback test.
*
* @note Ensure that you call this method to stop the loopback test after
* calling the \ref IAudioDeviceManager::startAudioDeviceLoopbackTest
* "startAudioDeviceLoopbackTest" method.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int stopAudioDeviceLoopbackTest() = 0;
/** The status of following system default playback device.
@note The status of following system default playback device.
@param enable Variable to whether the current device follow system default playback device or not.
- true: The current device will change when the system default playback device changed.
- false: The current device will change only current device is removed.
@return
- 0: Success.
- < 0: Failure.
*/
virtual int followSystemPlaybackDevice(bool enable) = 0;
/** The status of following system default recording device.
@note The status of following system default recording device.
@param enable Variable to whether the current device follow system default recording device or not.
- true: The current device will change when the system default recording device changed.
- false: The current device will change only current device is removed.
@return
- 0: Success.
- < 0: Failure.
*/
virtual int followSystemRecordingDevice(bool enable) = 0;
/** The status of following system default loopback device.
@note The status of following system default loopback device.
@param enable Variable to whether the current device follow system default loopback device or not.
- true: The current device will change when the system default loopback device changed.
- false: The current device will change only current device is removed.
@return
- 0: Success.
- < 0: Failure.
*/
virtual int followSystemLoopbackDevice(bool enable) = 0;
/**
* Releases all IAudioDeviceManager resources.
*/
virtual void release() = 0;
};
} // namespace rtc
} // namespace agora

View File

@@ -0,0 +1,570 @@
//
// Agora SDK
//
// Copyright (c) 2018 Agora.io. All rights reserved.
//
#pragma once // NOLINT(build/header_guard)
#include <cstring>
#include "AgoraBase.h"
#include "AgoraRefPtr.h"
#include <aosl/api/cpp/aosl_ares_class.h>
namespace agora {
namespace media {
namespace base {
class IAudioFrameObserver;
} // namespace base
} // namespace media
namespace rtc {
static const int kAdmMaxDeviceNameSize = 128;
static const int kAdmMaxGuidSize = 128;
static const int kIntervalInMillseconds = 200;
#if defined(_WIN32) || (defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONE)
/**
* The struct of AudioDeviceInfo.
*
* @note
* This struct applies to Windows and macOS only.
*/
struct AudioDeviceInfo {
/**
* The name of the device. The maximum name size is 128 bytes. The default value is 0.
*/
char deviceName[kAdmMaxDeviceNameSize];
/**
* The type name of the device. such as Built-in, USB, HDMI, etc. The maximum size is 128 bytes. The default value is 0.
* @note This member applies to macOS only.
*/
char deviceTypeName[kAdmMaxDeviceNameSize];
/**
* The ID of the device. The maximum size is 128 bytes. The default value is 0.
*/
char deviceId[kAdmMaxGuidSize];
/**
* Determines whether the current device is selected for audio capturing or playback.
* - true: Select the current device for audio capturing or playback.
* - false: (Default) Do not select the current device for audio capturing or playback.
*/
bool isCurrentSelected;
/**
* Determines whether the current device is the audio playout device.
* - true: (Default) The current device is the playout device.
* - false: The current device is not the playout device.
*/
bool isPlayoutDevice;
AudioDeviceInfo() : isCurrentSelected(false),
isPlayoutDevice(true) {
memset(deviceName, 0, sizeof(deviceName));
memset(deviceTypeName, 0, sizeof(deviceTypeName));
memset(deviceId, 0, sizeof(deviceId));
}
};
#endif // _WIN32 || (TARGET_OS_MAC && !TARGET_OS_IPHONE)
/**
* The struct of LoopbackRecordingOption
*
* @note
*/
struct LoopbackRecordingOption {
/**
* the name of the device. the maximum name size is 128 bytes. the default value is 0.
*/
Optional<const char *> deviceName;
/**
* allow output device change when enable loopback recording.
*/
Optional<bool> allowDeviceChange;
};
/**
* The IAudioDeviceManagerObserver class.
*/
class IAudioDeviceManagerObserver
{
public:
virtual ~IAudioDeviceManagerObserver() {}
/**
* Occurs when the device state changes, for example, when a device is added or removed.
*
* To get the current information of the connected audio devices, call \ref agora::rtc::INGAudioDeviceManager::getNumberOfPlayoutDevices "getNumberOfPlayoutDevices".
*/
virtual void onDeviceStateChanged() = 0;
/**
* Occurs when the device state changes, for example, when a device is added or removed or default device change.
*
* @note
* This method applies to Windows only now.
*
* @param deviceId Pointer to the device ID.
* @param deviceType Device type: #MEDIA_DEVICE_TYPE.
* @param deviceState Device state: #MEDIA_DEVICE_STATE_TYPE..
*/
virtual void onAudioDeviceStateChanged(const char *deviceId, int deviceType, int deviceState) = 0;
/** Indicates incoming volume. This can be used to test microphone or speaker.
*
* @param deviceType Device type: #MEDIA_DEVICE_TYPE.
* @param volume volume between 0 (lowest volume) to 255 (highest volume).
*/
virtual void onVolumeIndication(int deviceType, int volume) = 0;
/**
* Occurs when the audio route changes.
*
* @param route The current audio route. See #AudioRoute.
*/
virtual void onRoutingChanged(AudioRoute route) = 0;
/**
* Occurs when the audio device volume changes.
*
* @param deviceType The device type, see #MEDIA_DEVICE_TYPE.
* @param volume The volume of the audio device.
* @param muted Whether the audio device is muted:
* - true: The audio device is muted.
* - false: The audio device is not muted.
*/
virtual void onAudioDeviceVolumeChanged(int deviceType, int volume, bool muted) = 0;
};
class IRecordingDeviceSource : public RefCountInterface {
public:
/**
* Initialize the recording device source.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int initRecording(const char* deviceName = NULL) = 0;
/**
* Start the recording device.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int startRecording(aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Stop the recording device.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int stopRecording(aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Registers an audio frame observer.
*
* @param observer The pointer to the IAudioFrameObserver object.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int registerAudioFrameObserver(media::IAudioPcmFrameSink* observer, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Releases the registered IAudioFrameObserver object.
*
* @param observer The pointer to the IAudioFrameObserver object created by the `registerAudioPcmDataCallback` method.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int unregisterAudioFrameObserver(media::IAudioPcmFrameSink* observer) = 0;
/**
* Set parameter to object loopback device;
* @param option
* - 0: Success.
* - < 0: Failure.
*/
virtual int setLoopbackDeviceParameter(const LoopbackRecordingOption &option, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
virtual ~IRecordingDeviceSource() {}
};
/**
* The INGAudioDeciceManager class.
*
* This class provides access to audio volume and audio route control, as well as device enumeration and
* selection on the PC.
*/
class INGAudioDeviceManager : public RefCountInterface {
public:
/**
* Creates a audio device source object and returns the pointer.
*
* @return
* - The pointer to \ref rtc::IRecordingDeviceSource "IRecordingDeviceSource", if the method call
* succeeds.
* - An empty pointer NULL: Failure.
*/
virtual agora_refptr<IRecordingDeviceSource> createRecordingDeviceSource(char deviceId[kAdmMaxDeviceNameSize]) = 0;
/**
* Sets the volume of the microphone.
* @param volume The volume of the microphone. The value range is [0, 255].
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setMicrophoneVolume(unsigned int volume, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Gets the volume of the microphone.
* @param volume The volume of the microphone.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getMicrophoneVolume(unsigned int& volume) = 0;
/**
* Sets the volume of the speaker.
* @param volume The volume of the speaker. The value range is [2, 255].
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setSpeakerVolume(unsigned int volume, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Gets the volume of the speaker.
* @param volume The volume of the speaker.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getSpeakerVolume(unsigned int& volume) = 0;
/**
* Captures or stops capturing the local audio with the microphone.
* @param mute Determines whether to capture or stop capturing the local audio with the microphone.
* - true: Stop capturing the local audio.
* - false: (Default) Capture the local audio.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setMicrophoneMute(bool mute, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Gets the mute state of the microphone.
* @param mute The mute state of the microphone.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getMicrophoneMute(bool& mute) = 0;
/**
* Plays or stops playing the remote audio with the speaker.
* @param mute Determines whether to play or stop playing the remote audio.
* - true: Stop playing the remote audio.
* - false: (Default) Play the remote audio.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setSpeakerMute(bool mute, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Gets the mute state of the speaker.
* @param mute A reference to the mute state of the speaker.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getSpeakerMute(bool& mute) = 0;
/**
* Get the playout parameters of audio device.
* @param params A point to the struct AudioParameters.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getPlayoutAudioParameters(AudioParameters* params) const = 0;
/**
* Get the record parameters of audio device.
* @param params A point to the struct AudioParameters.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getRecordAudioParameters(AudioParameters* params) const = 0;
#if defined(__ANDROID__) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)
/**
* Sets the default audio routing.
*
* This method allows apps to change the current audio route for the received audio.
* Noted: In Low Level API, we don't support default audio routing, i.e.,
* setDefaultAudioRouteToSpeakerphone. This can be done in RTC engine.
*
* @note
* This method applies to Android and iOS only.
*
* @param route The default audio route. See #AudioRoute.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setDefaultAudioRouting(AudioRoute route, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Changes the current audio routing.
*
* @note
* This method applies to Android and iOS only.
*
* @param route The audio route that you want to change to. See #AudioRoute.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int changeAudioRouting(AudioRoute route, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Changes the speaker status on/off.
*
* @note
* This method applies to Android and iOS only.
*
* @param enable on/off
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setAudioRoutingSpeakerOn(bool enable, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Gets the current audio routing.
*
* @note
* This method applies to Android and iOS only.
*
* @param route A reference to the audio route: AudioRoute.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getCurrentRouting(AudioRoute& route) = 0;
#endif // __ANDROID__ || TARGET_OS_IPHONE
#if defined(_WIN32) || (defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONE)
/**
* Gets the index numbers of all audio playout devices.
*
* @note
* This method applies to Windows or macOS only.
*
* @return
* - The index numbers of the audio playout devices: Success.
* - < 0: Failure.
*/
virtual int getNumberOfPlayoutDevices() = 0;
/**
* Gets the index numbers of all audio recording devices.
*
* @note
* This method applies to Windows or macOS only.
*
* @return
* - The index numbers of the audio recording devices: Success.
* - < 0: Failure.
*/
virtual int getNumberOfRecordingDevices() = 0;
/**
* Gets the information of the current audio playout device.
*
* @note
* This method applies to Windows or macOS only.
*
* @param index The index number of the current audio playout device.
* @return
* The information of the audio playout device. See \ref agora::rtc::AudioDeviceInfo "AudioDeviceInfo".
*/
virtual AudioDeviceInfo getPlayoutDeviceInfo(int index) = 0;
/**
* Gets the information of the current recording device.
*
* @note
* This method applies to Windows or macOS only.
*
* @param index The index number of the current recording device.
* @return
* The information of the recording device. See \ref agora::rtc::AudioDeviceInfo "AudioDeviceInfo".
*/
virtual AudioDeviceInfo getRecordingDeviceInfo(int index) = 0;
/**
* Sets the audio playback device.
*
* @note
* This method applies to Windows or macOS only.
*
* @param index The index number of the audio playout device.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setPlayoutDevice(int index, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Sets the recording device.
*
* @note
* This method applies to Windows or macOS only.
*
* @param index The index number of the recording device.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setRecordingDevice(int index, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/** The status of following system default playback device.
@note The status of following system default playback device.
@param enable Variable to whether the current device follow system default playback device or not.
- true: The current device will change when the system default playback device changed.
- false: The current device will change only current device is removed.
@return
- 0: Success.
- < 0: Failure.
*/
virtual int followSystemPlaybackDevice(bool enable, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/** The status of following system default recording device.
@note The status of following system default recording device.
@param enable Variable to whether the current device follow system default recording device or not.
- true: The current device will change when the system default recording device changed.
- false: The current device will change only current device is removed.
@return
- 0: Success.
- < 0: Failure.
*/
virtual int followSystemRecordingDevice(bool enable, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
#endif // _WIN32 || (TARGET_OS_MAC && !TARGET_OS_IPHONE)
#if defined(_WIN32)
/**
* Sets the volume of the app.
*
* @note
* This method applies to Windows only.
*
* @param volume The volume of the app. The value range is [0, 255].
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setApplicationVolume(unsigned int volume, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Gets the volume of the app.
*
* @note
* This method applies to Windows only.
*
* @param volume The volume of the app. The value range is [0, 255].
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getApplicationVolume(unsigned int& volume) = 0;
/**
* Sets the mute state of the app.
*
* @note
* This method applies to Windows only.
*
* @param mute Determines whether to set the app to the mute state.
* - true: Set the app to the mute state.
* - false: (Default) Do not set the app to the mute state.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setApplicationMuteState(bool mute, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Gets the mute state of the app.
*
* @note
* This method applies to Windows only.
*
* @param mute A reference to the mute state of the app.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getApplicationMuteState(bool& mute) = 0;
/**
* Gets the information of the current audio loopback device.
*
* @note
* This method applies to Windows or macOS only.
*
* @param index The index number of the current audio playout device.
* @return
* The information of the audio playout device. See \ref agora::rtc::AudioDeviceInfo "AudioDeviceInfo".
*/
virtual AudioDeviceInfo getLoopbackDeviceInfo(int index) = 0;
/**
* Sets the audio loopback device.
*
* @note
* This method applies to Windows only.
*
* @param index The index number of the audio playout device.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setLoopbackDevice(int index, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/** The status of following system default loopback device.
@note The status of following system default loopback device.
@param enable Variable to whether the current device follow system default loopback device or not.
- true: The current device will change when the system default loopback device changed.
- false: The current device will change only current device is removed.
@return
- 0: Success.
- < 0: Failure.
*/
virtual int followSystemLoopbackDevice(bool enable, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
#endif // _WIN32
/**
* Registers an IAudioDeviceManagerObserver object.
*
* You need to implement the IAudioDeviceManageObserver class in this method, and register callbacks
* according to your scenario.
*
* @param observer A pointer to the IAudioDeviceManagerObserver class.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int registerObserver(IAudioDeviceManagerObserver* observer, void(*safeDeleter)(IAudioDeviceManagerObserver*) = NULL, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Releases the IAudioDeviceManagerObserver object.
* @param observer The pointer to the IAudioDeviceManagerObserver class registered using #registerObserver.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int unregisterObserver(IAudioDeviceManagerObserver* observer) = 0;
virtual int setupAudioAttributeContext(void* audioAttr, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
protected:
~INGAudioDeviceManager() {}
};
} //namespace rtc
} // namespace agora

View File

@@ -0,0 +1,909 @@
// Copyright (c) 2018 Agora.io. All rights reserved
// This program is confidential and proprietary to Agora.io.
// And may not be copied, reproduced, modified, disclosed to others, published
// or used, in whole or in part, without the express prior written permission
// of Agora.io.
#pragma once // NOLINT(build/header_guard)
#include "AgoraBase.h"
#include <aosl/api/cpp/aosl_ares_class.h>
// FIXME(Ender): use this class instead of AudioSendStream as local track
namespace agora {
namespace rtc {
class IAudioTrackStateObserver;
class IAudioFilter;
class IAudioSinkBase;
class IMediaPacketReceiver;
class IAudioEncodedFrameReceiver;
/**
* Properties of audio frames expected by a sink.
*
* @note The source determines the audio frame to be sent to the sink based on a variety of factors,
* such as other sinks or the capability of the source.
*
*/
struct AudioSinkWants {
/** The sample rate of the audio frame to be sent to the sink. */
int samplesPerSec;
/** The number of audio channels of the audio frame to be sent to the sink. */
size_t channels;
AudioSinkWants() : samplesPerSec(0),
channels(0) {}
AudioSinkWants(int sampleRate, size_t chs) : samplesPerSec(sampleRate),
channels(chs) {}
AudioSinkWants(int sampleRate, size_t chs, int trackNum) : samplesPerSec(sampleRate), channels(chs) {}
};
/**
* The IAudioTrack class.
*/
class IAudioTrack : public RefCountInterface {
public:
/**
* The position of the audio filter in audio frame.
*/
enum AudioFilterPosition {
/**
* Work on the local playback
*/
RecordingLocalPlayback,
/**
* Work on the post audio processing.
*/
PostAudioProcessing,
/**
* Work on the remote audio before mixing.
*/
RemoteUserPlayback,
/**
* Work on the pcm source.
*/
PcmSource,
/**
* Work on the sending branch of the pcm source.
*/
PcmSourceSending,
/**
* Work on the local playback branch of the pcm source.
*/
PcmSourceLocalPlayback,
/**
* Work on the playback after remote-audio mix.
*/
RemoteMixedPlayback,
};
public:
/**
* Adjusts the playback volume.
* @param volume The playback volume. The value ranges between 0 and 100 (default).
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int adjustPlayoutVolume(int volume, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Gets the current playback volume.
* @param volume A pointer to the playback volume.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getPlayoutVolume(int* volume) = 0;
/**
* Adds an audio filter.
*
* By adding an audio filter, you can apply various audio effects to the audio, for example, voice change.
* @param filter A pointer to the audio filter. See \ref agora::rtc::IAudioFilter "IAudioFilter".
* @param position The position of the audio filter. See \ref agora::rtc::IAudioTrack::AudioFilterPosition "AudioFilterPosition".
* @param extContext The context of current filter. See \ref agora::rtc::ExtensionContext "ExtensionContext".
* @return
* - `true`: Success.
* - `false`: Failure.
*/
virtual bool addAudioFilter(agora_refptr<IAudioFilter> filter, AudioFilterPosition position, ExtensionContext *extContext = NULL, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Removes the audio filter added by callling `addAudioFilter`.
*
* @param filter The pointer to the audio filter that you want to remove. See \ref agora::rtc::IAudioFilter "IAudioFilter".
* @param position The position of the audio filter. See #AudioFilterPosition.
* @return
* - `true`: Success.
* - `false`: Failure.
*/
virtual bool removeAudioFilter(agora_refptr<IAudioFilter> filter, AudioFilterPosition position, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Enable / Disable specified audio filter
* @param id id of the filter
* @param enable enable / disable the filter with given id
* @param position The position of the audio filter. See #AudioFilterPosition.
* @return
* - 0: success
* - <0: failure
*/
virtual int enableAudioFilter(const char* id, bool enable, AudioFilterPosition position, aosl_ref_t ares = AOSL_REF_INVALID) {
(void)id;
(void)enable;
(void)position;
return -1;
}
/**
* set the properties of the specified audio filter
* @param id id of the filter
* @param key key of the property
* @param jsonValue json str value of the property
* @param position The position of the audio filter. See #AudioFilterPosition.
* @return
* - 0: success
* - <0: failure
*/
virtual int setFilterProperty(const char* id, const char* key, const char* jsonValue, AudioFilterPosition position, aosl_ref_t ares = AOSL_REF_INVALID) {
(void)id;
(void)key;
(void)jsonValue;
(void)position;
return -1;
}
/**
* get the properties of the specified video filter
* @param id id of the filter
* @param key key of the property
* @param jsonValue json str value of the property
* @param bufSize max length of the json value buffer
* @param position The position of the audio filter. See #AudioFilterPosition.
* @return
* - 0: success
* - <0: failure
*/
virtual int getFilterProperty(const char* id, const char* key, char* jsonValue, size_t bufSize, AudioFilterPosition position) {
(void)id;
(void)key;
(void)jsonValue;
(void)bufSize;
(void)position;
return -1;
}
/**
* Gets the audio filter by its name.
*
* @param name The name of the audio filter.
* @param position The position of the audio filter. See #AudioFilterPosition.
* @return
* - The pointer to the audio filter: Success.
* - A null pointer: Failure.
*/
virtual agora_refptr<IAudioFilter> getAudioFilter(const char *name, AudioFilterPosition position) const = 0;
/**
* Adds an audio sink to get PCM data from the audio track.
*
* @param sink The pointer to the audio sink. See \ref agora::rtc::IAudioSinkBase "IAudioSinkBase".
* @param wants The properties an audio frame should have when it is delivered to the sink. See \ref agora::rtc::AudioSinkWants "AudioSinkWants".
* @return
* - `true`: Success.
* - `false`: Failure.
*/
virtual bool addAudioSink(agora_refptr<IAudioSinkBase> sink, const AudioSinkWants& wants, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Removes an audio sink.
*
* @param sink The pointer to the audio sink to be removed. See \ref agora::rtc::IAudioSinkBase "IAudioSinkBase".
* @return
* - `true`: Success.
* - `false`: Failure.
*/
virtual bool removeAudioSink(agora_refptr<IAudioSinkBase> sink, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
};
/**
* The observer of the local audio track.
*/
class ILocalAudioTrackObserver {
public:
virtual ~ILocalAudioTrackObserver() {}
/**
* Occurs when the state of a local audio track changes.
*
* @param state The state of the local audio track.
* @param reasonCode The error information for a state failure: \ref agora::rtc::LOCAL_AUDIO_STREAM_REASON "LOCAL_AUDIO_STREAM_REASON".
*/
virtual void onLocalAudioTrackStateChanged(LOCAL_AUDIO_STREAM_STATE state,
LOCAL_AUDIO_STREAM_REASON reasonCode) = 0;
};
/**
* `ILocalAudioTrack` is the basic class for local audio tracks, providing main methods of local audio tracks.
*
* You can create a local audio track by calling one of the following methods:
* - `createLocalAudioTrack`
* - `createCustomAudioTrack`
* - `createMediaPlayerAudioTrack`
* @if (!Linux)
* You can also use the APIs in the \ref agora::rtc::INGAudioDeviceManager "IAudioDeviceManager" class if multiple recording devices are available in the system.
* @endif
*
* After creating local audio tracks, you can publish one or more local audio
* tracks by calling \ref agora::rtc::ILocalUser::publishAudio "publishAudio".
*/
class ILocalAudioTrack : public IAudioTrack {
public:
/**
* Statistics of a local audio track.
*/
struct LocalAudioTrackStats {
/**
* The source ID of the local audio track.
*/
uint32_t source_id;
/**
* The number of audio frames in the buffer.
*
* When sending PCM data, the PCM data is first stored in a buffer area.
* Then a thread gets audio frames from the buffer and sends PCM data.
*/
uint32_t buffered_pcm_data_list_size;
/**
* The number of audio frames missed by the thread that gets PCM data from the buffer.
*/
uint32_t missed_audio_frames;
/**
* The number of audio frames sent by the thread that gets PCM data from the buffer.
*/
uint32_t sent_audio_frames;
/**
* The number of audio frames sent by the user.
*/
uint32_t pushed_audio_frames;
/**
* The number of dropped audio frames caused by insufficient buffer size.
*/
uint32_t dropped_audio_frames;
/**
* The number of playout audio frames.
*/
uint32_t playout_audio_frames;
/**
* The type of audio effect.
*/
uint32_t effect_type;
/**
* Whether the hardware ear monitor is enabled.
*/
uint32_t hw_ear_monitor;
/**
* Whether the local audio track is enabled.
*/
bool enabled;
/**
* The volume that ranges from 0 to 255.
*/
uint32_t audio_volume; // [0,255]
LocalAudioTrackStats() : source_id(0),
buffered_pcm_data_list_size(0),
missed_audio_frames(0),
sent_audio_frames(0),
pushed_audio_frames(0),
dropped_audio_frames(0),
playout_audio_frames(0),
effect_type(0),
hw_ear_monitor(0),
enabled(false),
audio_volume(0) {}
};
public:
/**
* Enables or disables the local audio track.
*
* Once the local audio is enabled, the SDK allows for local audio capturing, processing, and encoding.
*
* @param enable Whether to enable the audio track:
* - `true`: Enable the local audio track.
* - `false`: Disable the local audio track.
*/
virtual int setEnabled(bool enable, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Gets whether the local audio track is enabled.
* @return Whether the local audio track is enabled:
* - `true`: The local track is enabled.
* - `false`: The local track is disabled.
*/
virtual bool isEnabled() const = 0;
/**
* Gets the state of the local audio.
* @return The state of the local audio: #LOCAL_AUDIO_STREAM_STATE: Success.
*/
virtual LOCAL_AUDIO_STREAM_STATE getState() = 0;
/**
* Gets the statistics of the local audio track: LocalAudioTrackStats.
* @return The statistics of the local audio: LocalAudioTrackStats: Success.
*/
virtual LocalAudioTrackStats GetStats() = 0;
/**
* Adjusts the audio volume for publishing.
*
* @param volume The volume for publishing. The value ranges between 0 and 100 (default).
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int adjustPublishVolume(int volume, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Gets the current volume for publishing.
* @param volume A pointer to the publishing volume.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getPublishVolume(int* volume) = 0;
/**
* Enables or disables local playback.
* @param enable Whether to enable local playback:
* - `true`: Enable local playback.
* - `false`: Disable local playback.
* @param sync Whether to destroy local playback synchronously:
* - `true`: Destroy local playback synchronously.
* - `false`: Destroy local playback asynchronously.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int enableLocalPlayback(bool enable, bool sync = true, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Enables in-ear monitoring (for Android and iOS only).
*
* @param enabled Determines whether to enable in-ear monitoring.
* - true: Enable.
* - false: (Default) Disable.
* @param includeAudioFilters The type of the ear monitoring: #EAR_MONITORING_FILTER_TYPE
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int enableEarMonitor(bool enable, int includeAudioFilters, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/** Register an local audio track observer
*
* @param observer A pointer to the local audio track observer: \ref agora::rtc::ILocalAudioTrackObserver
* "ILocalAudioTrackObserver".
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int registerTrackObserver(ILocalAudioTrackObserver* observer, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/** Releases the local audio track observer
*
* @param observer A pointer to the local audio track observer: \ref agora::rtc::ILocalAudioTrackObserver
* "ILocalAudioTrackObserver".
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int unregisterTrackObserver(ILocalAudioTrackObserver* observer) = 0;
/** set Max buffered audio frame number
*
* @param number : the buffer number setunit is 10ms
*
*/
virtual void setMaxBufferedAudioFrameNumber(int number, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/** clear sender buffer
*
* @return
* - >= 0: Frame number in sender buffer.
* - < 0: Failure.
*/
virtual int ClearSenderBuffer() = 0;
protected:
~ILocalAudioTrack() {}
};
/**
* The statistics of a remote audio track.
*/
struct RemoteAudioTrackStats {
/**
* The user ID of the remote user who sends the audio track.
*/
uid_t uid;
/**
* The audio quality of the remote audio track: #QUALITY_TYPE.
*/
int quality;
/**
* The network delay (ms) from the sender to the receiver.
*/
int network_transport_delay;
/**
* The delay (ms) from the receiver to the jitter buffer.
*/
uint32_t jitter_buffer_delay;
/**
* The audio frame loss rate in the reported interval.
*/
int audio_loss_rate;
/**
* The number of audio channels.
*/
int num_channels;
/**
* The sample rate (Hz) of the received audio track in the reported interval.
*/
int received_sample_rate;
/**
* The average bitrate (Kbps) of the received audio track in the reported interval.
* */
int received_bitrate;
/**
* The total freeze time (ms) of the remote audio track after the remote user joins the channel.
* In a session, audio freeze occurs when the audio frame loss rate reaches 4%.
* The total audio freeze time = The audio freeze number × 2 seconds.
*/
int total_frozen_time;
/**
* The total audio freeze time as a percentage (%) of the total time when the audio is available.
* */
int frozen_rate;
/**
* The number of audio bytes received.
*/
int64_t received_bytes;
/**
* The average packet waiting time (ms) in the jitter buffer.
*/
int mean_waiting_time;
/**
* The samples of expanded speech.
*/
size_t expanded_speech_samples;
/**
* The samples of expanded noise.
*/
size_t expanded_noise_samples;
/**
* The timestamps since last report.
*/
uint32_t timestamps_since_last_report;
/**
* The minimum sequence number.
*/
uint16_t min_sequence_number;
/**
* The maximum sequence number.
*/
uint16_t max_sequence_number;
/**
* The audio energy.
*/
int32_t audio_level;
/**
* audio downlink average process time
*/
uint32_t downlink_process_time_ms;
/**
* audio neteq loss because of expired
*/
uint32_t packet_expired_loss;
/**
* audio neteq packet arrival expired time ms
*/
uint32_t packet_max_expired_ms;
/**
* audio neteq jitter peak num in two second
*/
uint32_t burst_peak_num;
/**
* audio neteq jitter calc by burst opti feature
*/
uint32_t burst_jitter;
/**
* audio base target level
*/
uint32_t target_level_base_ms;
/**
* audio average target level
*/
uint32_t target_level_prefered_ms;
/**
* audio average accelerate ratio in 2s
*/
uint16_t accelerate_rate;
/**
* audio average preemptive expand ratio in 2s
*/
uint16_t preemptive_expand_rate;
/**
* The count of 80 ms frozen in 2 seconds
*/
uint16_t frozen_count_80_ms;
/**
* The time of 80 ms frozen in 2 seconds
*/
uint16_t frozen_time_80_ms;
/**
* The count of 200 ms frozen in 2 seconds
*/
uint16_t frozen_count_200_ms;
/**
* The time of 200 ms frozen in 2 seconds
*/
uint16_t frozen_time_200_ms;
/**
* The full time of 80 ms frozen in 2 seconds
*/
uint16_t full_frozen_time_80_ms;
/**
* The full time of 200 ms frozen in 2 seconds
*/
uint16_t full_frozen_time_200_ms;
/**
* The estimate delay
*/
uint32_t delay_estimate_ms;
/**
* The MOS value
*/
uint32_t mos_value;
/**
* If the packet loss concealment (PLC) occurs for N consecutive times, freeze is considered as PLC occurring for M consecutive times.
* freeze cnt = (n_plc - n) / m
*/
uint32_t frozen_rate_by_custom_plc_count;
/**
* The number of audio packet loss concealment
*/
uint32_t plc_count;
/**
* Duration of inbandfec
*/
int32_t fec_decode_ms;
/**
* The count of 10 ms frozen in 2 seconds
*/
uint16_t frozen_count_10_ms;
/**
* The total time (ms) when the remote user neither stops sending the audio
* stream nor disables the audio module after joining the channel.
*/
uint64_t total_active_time;
/**
* The total publish duration (ms) of the remote audio stream.
*/
uint64_t publish_duration;
int32_t e2e_delay_ms;
/**
* e2e_delay_ calculated by the new algorithm
*/
int32_t new_e2e_delay_ms;
/**
* Quality of experience (QoE) of the local user when receiving a remote audio stream. See #EXPERIENCE_QUALITY_TYPE.
*/
int qoe_quality;
/**
* The reason for poor QoE of the local user when receiving a remote audio stream. See #EXPERIENCE_POOR_REASON.
*/
int32_t quality_changed_reason;
/**
* The type of downlink audio effect.
*/
int32_t downlink_effect_type;
RemoteAudioTrackStats() :
uid(0),
quality(0),
network_transport_delay(0),
jitter_buffer_delay(0),
audio_loss_rate(0),
num_channels(0),
received_sample_rate(0),
received_bitrate(0),
total_frozen_time(0),
frozen_rate(0),
received_bytes(0),
mean_waiting_time(0),
expanded_speech_samples(0),
expanded_noise_samples(0),
timestamps_since_last_report(0),
min_sequence_number(0xFFFF),
max_sequence_number(0),
audio_level(0),
downlink_process_time_ms(0),
packet_expired_loss(0),
packet_max_expired_ms(0),
burst_peak_num(0),
burst_jitter(0),
target_level_base_ms(0),
target_level_prefered_ms(0),
accelerate_rate(0),
preemptive_expand_rate(0),
frozen_count_80_ms(0),
frozen_time_80_ms(0),
frozen_count_200_ms(0),
frozen_time_200_ms(0),
full_frozen_time_80_ms(0),
full_frozen_time_200_ms(0),
delay_estimate_ms(0),
mos_value(0),
frozen_rate_by_custom_plc_count(0),
plc_count(0),
fec_decode_ms(-1),
frozen_count_10_ms(0),
total_active_time(0),
publish_duration(0),
e2e_delay_ms(0),
new_e2e_delay_ms(0),
qoe_quality(0),
quality_changed_reason(0),
downlink_effect_type(0) {}
};
/**
* Properties of receive parameters for IAudioEncodedFrameReceiver
*
*/
struct AudioEncFrameRecvParams {
/**
* The callback mode of IAudioEncodedFrameReceiver
*/
enum ReceiveMode {
/**
* IAudioEncodedFrameReceiver callback the down-link audio packet directly
*/
ORIGINAL = 0,
/**
* IAudioEncodedFrameReceiver whill callback the original down-link audio packet while
* the codec of down-link packet is same as target_codec.
*
* Othewise convert down-link audio packet to new target packet which parameter contain
* the combination of (target_codec, target_sample_rate, target_sample_rate).
*/
MATCHED_CODEC = 1,
/**
* IAudioEncodedFrameReceiver whill callback the original down-link audio packet while
* the combination of (codec, sampling rate, channels) of down-link packet is same as
* the combination of (target_codec, target_sample_rate, target_sample_rate).
*
* Othewise convert down-link audio packet to new target packet which parameter contain
* the combination of (target_codec, target_sample_rate, target_sample_rate).
*/
MATCHED_ALL = 2,
};
/**
* The trans mode of audio packet
*/
ReceiveMode receive_mode;
/**
* The audio codec of target audio packet
*/
AUDIO_CODEC_TYPE target_codec;
/**
* The sample rate HZ of target audio packet
*/
int32_t target_sample_rate;
/**
* The channel numbers of target audio packet
*/
int32_t target_num_channels;
AudioEncFrameRecvParams() :
receive_mode(ORIGINAL),
target_codec(AUDIO_CODEC_AACLC),
target_sample_rate(0),
target_num_channels(0) {}
AudioEncFrameRecvParams(const AudioEncFrameRecvParams& src_params) {
receive_mode = src_params.receive_mode;
target_codec = src_params.target_codec;
target_sample_rate = src_params.target_sample_rate;
target_num_channels = src_params.target_num_channels;
}
};
/**
* The IRemoteAudioTrack class.
*/
class IRemoteAudioTrack : public IAudioTrack {
public:
/**
* Gets the statistics of the remote audio track.
* @param stats A reference to the statistics of the remote audio track: RemoteAudioTrackStats.
* @return
* - `true`: Success.
* - `false`: Failure.
*/
virtual bool getStatistics(RemoteAudioTrackStats& stats) = 0;
/**
* Gets the state of the remote audio.
* @return The state of the remote audio: #REMOTE_AUDIO_STATE.
*/
virtual REMOTE_AUDIO_STATE getState() = 0;
/**
* Registers an `IMediaPacketReceiver` object.
*
* You need to implement the `IMediaPacketReceiver` class in this method. Once you successfully register
* the media packet receiver, the SDK triggers the `onMediaPacketReceived` callback when it receives an
* audio packet.
*
* @param packetReceiver The pointer to the `IMediaPacketReceiver` object.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int registerMediaPacketReceiver(IMediaPacketReceiver* packetReceiver, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Releases the `IMediaPacketReceiver` object.
* @param packetReceiver The pointer to the `IMediaPacketReceiver` object.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int unregisterMediaPacketReceiver(IMediaPacketReceiver* packetReceiver) = 0;
/**
* Registers an `IAudioEncodedFrameReceiver` object.
*
* You need to implement the `IAudioEncodedFrameReceiver` class in this method. Once you successfully register
* the media packet receiver, the SDK triggers the `onEncodedAudioFrameReceived` callback when it receives an
* audio packet.
*
* @param packetReceiver The pointer to the `IAudioEncodedFrameReceiver` object.
* @param recvParams The parameter
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int registerAudioEncodedFrameReceiver(IAudioEncodedFrameReceiver* packetReceiver,
const AudioEncFrameRecvParams& recvParams,
aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Releases the `IAudioEncodedFrameReceiver` object.
* @param packetReceiver The pointer to the `IAudioEncodedFrameReceiver` object.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int unregisterAudioEncodedFrameReceiver(IAudioEncodedFrameReceiver* packetReceiver) = 0;
/** Sets the sound position and gain
@param pan The sound position of the remote user. The value ranges from -1.0 to 1.0:
- 0.0: the remote sound comes from the front.
- -1.0: the remote sound comes from the left.
- 1.0: the remote sound comes from the right.
@param gain Gain of the remote user. The value ranges from 0.0 to 100.0. The default value is 100.0 (the original gain of the remote user). The smaller the value, the less the gain.
@return
- 0: Success.
- < 0: Failure.
*/
virtual int setRemoteVoicePosition(float pan, float gain, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/** Sets the volume of each audio decoded channel
@param decoded_index The channel index of the remote user. The value ranges from 0 to 100:
@param volume The channel index of the remote user. The value ranges from 0 to 100.
- 0: mute the channel.
- 100: keep the origin volume of the channel.
@return
- 0: Success.
- < 0: Failure.
*/
virtual int adjustDecodedAudioVolume(int decoded_index, int volume, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/** mute remote stream from timestamp
@note
- unmuteRemoteFromTimestamp should be called after muteRemoteFromTimestamp, othewise this stream will be muted all time
@param timestamp The rtp timestamp of start mute
@return
- 0: Success.
- < 0: Failure.
*/
virtual int muteRemoteFromTimestamp(uint32_t timestamp) = 0;
/** unmute remote stream from timestamp
@note
- unmuteRemoteFromTimestamp should be called after muteRemoteFromTimestamp, othewise this stream will be muted all time
@param timestamp The rtp timestamp of start unmute
@return
- 0: Success.
- < 0: Failure.
*/
virtual int unmuteRemoteFromTimestamp(uint32_t timestamp) = 0;
/** set percentage of audio acceleration during poor network
@note
- The relationship between this percentage and the degree of audio acceleration is non-linear and varies with different audio material.
@param percentage The percentage of audio acceleration. The value ranges from 0 to 100. The higher the
* percentage, the faster the acceleration. The default value is 100 (no change to the acceleration):
- 0: disable audio acceleration.
- > 0: enable audio acceleration.
@return
- 0: Success.
- < 0: Failure.
*/
virtual int adjustAudioAcceleration(int percentage, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/** set percentage of audio deceleration during poor network
@note
- The relationship between this percentage and the degree of audio deceleration is non-linear and varies with different audio material.
@param percentage The percentage of audio deceleration. The value ranges from 0 to 100. The higher the
* percentage, the faster the deceleration. The default value is 100 (no change to the deceleration):
- 0: disable audio deceleration.
- > 0: enable audio deceleration.
@return
- 0: Success.
- < 0: Failure.
*/
virtual int adjustAudioDeceleration(int percentage, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/** enable spatial audio
@param enabled enable/disable spatial audio:
- true: enable spatial audio.
- false: disable spatial audio.
@return
- 0: Success.
- < 0: Failure.
*/
virtual int enableSpatialAudio(bool enabled, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/** Sets remote user parameters for spatial audio
@param params spatial audio parameters
@return
- 0: Success.
- < 0: Failure.
*/
virtual int setRemoteUserSpatialAudioParams(const agora::SpatialAudioParams& params, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
};
} // namespace rtc
} // namespace agora

View File

@@ -0,0 +1,569 @@
//
// Agora SDK
//
// Copyright (c) 2019 Agora.io. All rights reserved.
//
#pragma once // NOLINT(build/header_guard)
#include "AgoraBase.h"
#include "AgoraRefPtr.h"
#include <aosl/api/cpp/aosl_ares_class.h>
namespace agora {
namespace rtc {
class IVideoSinkBase;
class ICameraCaptureObserver;
/**
* The ICameraCapturer class, which provides access to a camera capturer.
*/
class ICameraCapturer : public RefCountInterface {
public:
/**
* The camera source.
*/
enum CAMERA_SOURCE {
/**
* The camera source is the rear camera.
*/
CAMERA_BACK,
/**
* The camera source is the front camera.
*/
CAMERA_FRONT,
/**
* The camera source is the extra camera.
*/
CAMERA_EXTRA,
};
/**
* The camera state.
*/
enum CAMERA_STATE {
/**
* The camera source is started.
*/
CAMERA_STARTED,
/**
* The camera source is stopped.
*/
CAMERA_STOPPED,
};
// Interface for receiving information about available camera devices.
/**
* The IDeviceInfo class, which manages the information of available cameras.
*/
class IDeviceInfo {
public:
virtual ~IDeviceInfo() {}
/**
* Releases the device.
*/
virtual void release() = 0;
/**
* Gets the number of all available cameras.
* @return The number of all available cameras.
*/
virtual uint32_t NumberOfDevices() = 0;
/**
* Gets the name of a specified camera.
* @param deviceNumber The index number of the device.
* @param deviceNameUTF8 The name of the device.
* @param deviceNameLength The length of the device name.
* @param deviceUniqueIdUTF8 The unique ID of the device.
* @param deviceUniqueIdLength The length of the device ID.
* @param productUniqueIdUTF8 The unique ID of the product.
* @param productUniqueIdLength The length of the product ID.
* @param deviceTypeUTF8 The camera type of the device.
* @param deviceTypeLength The length of the camera type.
* @return
* The name of the device in the UTF8 format: Success.
*/
virtual int32_t GetDeviceName(uint32_t deviceNumber, char* deviceNameUTF8,
uint32_t deviceNameLength, char* deviceUniqueIdUTF8,
uint32_t deviceUniqueIdLength, char* productUniqueIdUTF8 = 0,
uint32_t productUniqueIdLength = 0,
char* deviceTypeUTF8 = 0, uint32_t deviceTypeLength = 0) = 0;
/**
* Sets the capability number for a specified device.
* @param deviceUniqueIdUTF8 The pointer to the ID of the device in the UTF8 format.
* @return
* The capability number of the device.
*/
virtual int32_t NumberOfCapabilities(const char* deviceUniqueIdUTF8) = 0;
/**
* Gets the capability of a specified device.
* @param deviceUniqueIdUTF8 The pointer to the ID of the device in the UTF8 format.
* @param deviceCapabilityNumber The capability number of the device.
* @param capability The reference to the video capability. See {@link VideoFormat}.
* @return
* The capability number of the device.
*/
virtual int32_t GetCapability(const char* deviceUniqueIdUTF8,
const uint32_t deviceCapabilityNumber,
VideoFormat& capability) = 0;
};
public:
#if defined(__ANDROID__) || (defined(__APPLE__) && TARGET_OS_IPHONE)
/**
* Sets the camera source.
*
* @note
* This method applies to Android and iOS only.
*
* @param source The camera source that you want to capture. See #CAMERA_SOURCE.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setCameraSource(CAMERA_SOURCE source, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Gets the camera source.
*
* @note
* This method applies to Android and iOS only.
*
* @return The camera source. See #CAMERA_SOURCE.
*/
virtual CAMERA_SOURCE getCameraSource() = 0;
/**
* Switch the camera source
*
* @note
* This method applies to Android and iOS only.
*/
virtual int switchCamera(aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Returns whether zooming is supported by the current device.
* @note
* This method applies to Android and iOS only.
* This interface returns valid values only after the device is initialized.
*
* @return
* - true: zooming is supported.
* - false: zooming is not supported or device is not initialized.
*/
virtual bool isZoomSupported() = 0;
/**
* Sets the zooming factor of the device.
*
* @note
* This method applies to Android and iOS only.
*
* @param zoomValue The zooming factor of the device.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int32_t setCameraZoom(float zoomValue, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Gets the max zooming factor of the device.
*
* @note
* This method applies to Android and iOS only.
*
* @return
* - The max zooming factor of the device
*/
virtual float getCameraMaxZoom() = 0;
/**
* Returns whether auto-focus is supported by the current device.
* @note
* This method applies to Android and iOS only.
* This interface returns valid values only after device is initialized.
*
* @return
* - true: auto-focus is supported.
* - false: auto-focus is not supported or device is not initialized.
*/
virtual bool isFocusSupported() = 0;
/**
* Sets the focus area of the current device.
* @note
* This method applies to Android and iOS only.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int32_t setCameraFocus(float x, float y, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Returns whether auto face focus is supported by the current device.
* @note
* This method applies to Android and iOS only.
* This interface returns valid values only after device is initialized.
*
* @return
* - true: auto-face-focus is supported.
* - false: auto-face-focus is not supported or device is not initialized.
*/
virtual bool isAutoFaceFocusSupported() = 0;
/**
* Enables or disables auto face focus.
* @note
* This method applies to Android and iOS only.
* This interface returns valid values only after device is initialized.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int32_t setCameraAutoFaceFocus(bool enable, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Enables or disables auto face detection.
* @note
* This method applies to Android and iOS only.
* This interface returns valid values only after device is initialized.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int32_t enableFaceDetection(bool enable, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Checks whether the camera face detect is supported.
*
* @return
* - true: The camera face detect is supported.
* - false: The camera face detect is not supported.
*/
virtual bool isCameraFaceDetectSupported() = 0;
/**
* Checks whether the camera flash function is supported.
*
* The SDK uses the front camera by default, so if you call `isCameraTorchSupported` directly,
* you can find out from the return value whether the device supports enabling the flash
* when using the front camera. If you want to check whether the device supports enabling the
* flash when using the rear camera, call \ref IRtcEngine::switchCamera "switchCamera"
* to switch the camera used by the SDK to the rear camera, and then call `isCameraTorchSupported`.
*
* @note
* - Call this method after the camera is started.
* - This method is for Android and iOS only.
* - On iPads with system version 15, even if `isCameraTorchSupported` returns true, you might
* fail to successfully enable the flash by calling \ref IRtcEngine::setCameraTorchOn "setCameraTorchOn"
* due to system issues.
*
* @return
* - true: The device supports enabling the flash.
* - false: The device does not support enabling the flash.
*/
virtual bool isCameraTorchSupported() = 0;
/**
* @note
* - Call this method after the camera is started.
* - This method is for Android and iOS only.
* - On iPads with system version 15, even if \ref IRtcEngine::isCameraTorchSupported "isCameraTorchSupported"
* returns true, you might fail to successfully enable the flash by calling `setCameraTorchOn` due to
* system issues.
*
* @param isOn Determines whether to enable the flash:
* - true: Enable the flash.
* - false: Disable the flash.
*
* @return
* - 0: Success
* - < 0: Failure
*/
virtual int setCameraTorchOn(bool on, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/** Checks whether the camera exposure function is supported.
*
* Ensure that you call this method after the camera starts, for example, by calling `startPreview` or `joinChannel`.
*
* @since v2.3.2.
* @return
* <ul>
* <li>true: The device supports the camera exposure function.</li>
* <li>false: The device does not support the camera exposure function.</li>
* </ul>
*/
virtual bool isCameraExposurePositionSupported() = 0;
/** Sets the camera exposure position.
*
* Ensure that you call this method after the camera starts, for example, by calling `startPreview` or `joinChannel`.
*
* A successful setCameraExposurePosition method call triggers the {@link IRtcEngineEventHandler#onCameraExposureAreaChanged onCameraExposureAreaChanged} callback on the local client.
* @since v2.3.2.
* @param positionXinView The horizontal coordinate of the touch point in the view.
* @param positionYinView The vertical coordinate of the touch point in the view.
*
* @return
* <ul>
* <li>0: Success.</li>
* <li>< 0: Failure.</li>
* </ul>
*/
virtual int setCameraExposurePosition(float positionXinView, float positionYinView, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Returns whether exposure value adjusting is supported by the current device.
* Exposure compensation is in auto exposure mode.
* @since v4.2.2.
* @note
* This method only supports Android and iOS.
* This interface returns valid values only after the device is initialized.
*
* @return
* - true: exposure value adjusting is supported.
* - false: exposure value adjusting is not supported or device is not initialized.
*/
virtual bool isCameraExposureSupported() = 0;
/**
* Sets the camera exposure ratio.
*
* @since v4.2.2.
* @param value Absolute EV bias will set to camera.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setCameraExposureFactor(float value, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
#if (defined(__APPLE__) && (TARGET_OS_IOS || (defined(TARGET_OS_VISION) && TARGET_OS_VISION)))
/**
* Enables or disables the AVCaptureMultiCamSession.
*
* @param enable Determines whether to use the AVCaptureMultiCamSession:
* - true: Enable the AVCaptureMultiCamSession.
* - false: Disable the AVCaptureMultiCamSession.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual bool enableMultiCamera(bool enable, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Checks whether the camera auto exposure function is supported.
*
* @return
* - true: The camera auto exposure function is supported.
* - false: The camera auto exposure function is not supported.
*/
virtual bool isCameraAutoExposureFaceModeSupported() = 0;
/**
* Enables the camera auto exposure face function.
*
* @param enabled Determines whether to enable the camera auto exposure face mode.
* - true: Enable the auto exposure face function.
* - false: Do not enable the auto exposure face function.
*
* @return
* <ul>
* <li>0: Success.</li>
* <li>< 0: Failure.</li>
* </ul>
*/
virtual int setCameraAutoExposureFaceModeEnabled(bool enabled, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* set camera stabilization mode.If open stabilization mode, fov will be smaller and capture latency will be longer.
*
* @param mode specifies the camera stabilization mode.
*/
virtual int setCameraStabilizationMode(CAMERA_STABILIZATION_MODE mode) = 0;
#endif
#elif defined(_WIN32) || (defined(__linux__) && !defined(__ANDROID__)) || \
(defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONE)
/**
* Creates a DeviceInfo object.
*
* @note
* This method applies to Windows, macOS, and Linux only.
* @return
* - The pointer to \ref agora::rtc::ICameraCapturer::IDeviceInfo "IDeviceInfo": Success.
* - An empty pointer NULL: Failure.
*/
virtual IDeviceInfo* createDeviceInfo() = 0;
/**
* Initializes the device with the device ID.
*
* @note
* This method applies to Windows, macOS, and Linux only.
*
* @param deviceId The pointer to the device ID.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int initWithDeviceId(const char* deviceId) = 0;
/**
* Initializes the device with the device name.
*
* @note
* This method applies to Windows, macOS, and Linux only.
*
* @param deviceName The pointer to the device name.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int initWithDeviceName(const char* deviceName) = 0;
#endif
#if defined(__APPLE__)
/**
* Checks whether the center stage is supported. Use this method after starting the camera.
*
* @return
* - true: The center stage is supported.
* - false: The center stage is not supported.
*/
virtual bool isCenterStageSupported() = 0;
/** Enables the camera Center Stage.
* @param enabled enable Center Stage:
* - true: Enable Center Stage.
* - false: Disable Center Stage.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int enableCenterStage(bool enabled) = 0;
#endif
/**
* Set the device orientation of the capture device
* @param VIDEO_ORIENTATION orientaion of the device 0(by default), 90, 180, 270
*/
virtual int setDeviceOrientation(VIDEO_ORIENTATION orientation, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Sets the format of the video captured by the camera.
*
* If you do not set the video capturing format, the SDK automatically chooses a proper format according to the video encoder configuration of the video track.
*
* @param capture_format The reference to the video format: VideoFormat.
*/
virtual int setCaptureFormat(const VideoFormat& capture_format, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Gets the format of the video captured by the camera.
* @return
* VideoFormat.
*/
virtual VideoFormat getCaptureFormat() = 0;
/**
* Register a camera observer.
*
* @param observer Instance of the capture observer.
*/
virtual int registerCameraObserver(ICameraCaptureObserver* observer, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Unregisters the camera observer.
*
* @param observer Instance of the capture observer.
*/
virtual int unregisterCameraObserver(ICameraCaptureObserver* observer) = 0;
protected:
~ICameraCapturer() {}
};
/**
* The ICameraCaptureObserver class, which handles camera capture events.
*/
class ICameraCaptureObserver {
public:
/**
* Occurs when the camera focus area changes.
*
* @note The SDK triggers this callback when the local user changes the camera focus position by
* calling the \ref agora::rtc::ICameraCapturer::setCameraFocus "setCameraFocus" method.
*
* @param imageWidth Width of the changed camera focus area.
* @param imageHeight Height of the changed camera focus area.
* @param x x coordinate of the changed camera focus area.
* @param y y coordinate of the changed camera focus area.
*/
virtual void onCameraFocusAreaChanged(int imageWidth, int imageHeight, int x, int y) {
(void) imageWidth;
(void) imageHeight;
(void) x;
(void) y;
}
/**
* Reports the face detection result of the local user. Applies to Android and iOS only.
*
* Once you enable face detection by calling \ref agora::rtc::ICameraCapturer::setCameraFaceDetection "setCameraFaceDetection" (true),
* you can get the following information on the local user in real-time:
* - The width and height of the local video.
* - The position of the human face in the local video.
* - The distance between the human face and the device screen.
* This value is based on the fitting calculation of the local video size and the position of the human face.
*
* @note
* - If the SDK does not detect a face, it reduces the frequency of this callback to reduce power consumption on the local device.
* - The SDK stops triggering this callback when a human face is in close proximity to the screen.
* - On Android, the distance value reported in this callback may be slightly different from the actual distance.
* Therefore, Agora does not recommend using it for accurate calculation.
*
* @param imageWidth The width (px) of the local video.
* @param imageHeight The height (px) of the local video.
* @param vecRectangle A Rectangle array of length 'numFaces', which represents the position and size of the human face on the local video
* - `x`: The x coordinate (px) of the human face in the local video. Taking the top left corner of the captured video as the origin,
* the x coordinate represents the relative lateral displacement of the top left corner of the human face to the origin.
* - `y`: The y coordinate (px) of the human face in the local video. Taking the top left corner of the captured video as the origin,
* the y coordinate represents the relative longitudinal displacement of the top left corner of the human face to the origin.
* - `width`: The width (px) of the human face in the captured video.
* - `height`: The height (px) of the human face in the captured video.
* @param vecDistance An int array of length 'numFaces', which represents distance (cm) between the human face and the screen.
* @param numFaces The number of faces detected. If the value is 0, it means that no human face is detected.
*/
virtual void onFacePositionChanged(
int imageWidth, int imageHeight, const Rectangle* vecRectangle, const int* vecDistance, int numFaces) {
(void) imageWidth;
(void) imageHeight;
(void) vecRectangle;
(void) vecDistance;
(void) numFaces;
}
/** Occurs when the camera exposure area changes.
*
* The SDK triggers this callback when the local user changes the camera exposure position by calling the setCameraExposurePosition method.
*
* @note This callback is for Android and iOS only.
*
* @param x x coordinate of the changed camera exposure area.
* @param y y coordinate of the changed camera exposure area.
* @param width Width of the changed camera exposure area.
* @param height Height of the changed camera exposure area.
*/
virtual void onCameraExposureAreaChanged(int x, int y, int width, int height) {
(void)x;
(void)y;
(void)width;
(void)height;
}
virtual void onCameraStateChanged(ICameraCapturer::CAMERA_STATE state, ICameraCapturer::CAMERA_SOURCE source) {
(void) state;
(void) source;
}
protected:
virtual ~ICameraCaptureObserver() {}
};
} // namespace rtc
} // namespace agora

View File

@@ -0,0 +1,166 @@
// Copyright (c) 2022 Agora.io. All rights reserved
// This program is confidential and proprietary to Agora.io.
// And may not be copied, reproduced, modified, disclosed to others, published
// or used, in whole or in part, without the express prior written permission
// of Agora.io.
#pragma once // NOLINT(build/header_guard)
#include "AgoraRefPtr.h"
#include "AgoraBase.h"
#include <aosl/api/cpp/aosl_ares_class.h>
namespace agora {
/**
* The definition of the DataChannelConfig struct.
*/
struct DataChannelConfig {
/**
* Whether this channel should sync with media stream:
* - true: sync .
* - false: not sync.
*/
bool syncWithMedia;
/**
* Whether this channel should ensure oredered message:
* - true: orderd .
* - false: not orderd.
*/
bool ordered;
/**
* Whether this channel should compress the data packet:
* - <= 0: We dont compress the data packet
* - > 0: Once the packet length exceeds the compressionLength, we compress it.
*/
int compressionLength;
// optional
Optional<int> channelId; // 0~7
/**
* The priority
*/
int32_t priority;
DataChannelConfig() :
syncWithMedia(false),
ordered(false),
compressionLength(0),
priority(-1) {}
};
/**
* The definition of the DataChannelInfo struct.
*/
struct DataChannelInfo {
/**
* The Id of the data channel
*/
int dataChannelId;
/**
* The metaData of the data channel
*/
util::AString metadata;
};
/**
* The definition of the DataChannelInfo struct.
*/
struct UserDataChannelInfo {
/**
* The user Id of the data channel
*/
util::AString userId;
/**
* The data channel infos
*/
const DataChannelInfo* infos;
/**
* The info size
*/
size_t info_size;
};
class ILocalDataChannel : public RefCountInterface {
public:
/**
* Send data packet to this data channel after publishing.
*
* @param [in] packet packet buffer pointer.
* @param [in] length packet buffer length.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int sendDataPacket(const char* packet, size_t length, uint64_t capture_time_ms, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Send meta data to this data channel before publishing.
*
* @param [in] metaData meta data pointer.
* @param [in] length meta data length.
* @return····
* - 0: Success.
* - < 0: Failure.
*/
virtual int setMetaData(const char* metaData, size_t length, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* return configured channel id
*
* @return
*/
virtual Optional<int> configuredChannelId() const = 0;
protected:
virtual ~ILocalDataChannel() {}
};
class IRemoteDataChannel: public RefCountInterface {
public:
virtual util::AString UserId() const = 0;
virtual int ChannelId() const = 0;
virtual util::AString Meta() = 0;
protected:
virtual ~IRemoteDataChannel() {}
};
class IDataChannelObserver {
public:
/**
* Occurs when the channe is ready to send the data packet.
* @param channel the published channel.
*/
virtual void onLocalDataChannelPublished(agora_refptr<ILocalDataChannel> channel) {}
/**
* Occurs when the the channe is added and ready to receive data packet.
* @param channel the remote channel pointer.
*/
virtual void onRemoteDataChannelSubscribed(agora_refptr<IRemoteDataChannel> channel) {}
/**
* Occurs when the the channe is removed.
* @param channel the remote channel pointer.
*/
virtual void onRemoteDataChannelUnsubscribed(agora_refptr<IRemoteDataChannel> channel) {}
/**
* Occurs when the packet is received.
* @param info the channel Info.
* @param packet the received packet.
*/
virtual void onRemoteDataPacketReceived(const UserDataChannelInfo& info, util::AString packet) {}
/**
* Occurs when the remote data channel info updated.
* @param modified_infos the modifed channel Infos, add or update.
* @param modified_infos_size the size of modifed channel Infos .
* @param deleted_infos the deleted channel Infos.
* @param deleted_infos_size the size of deleted channel Infos .
*/
virtual void onRemoteDataChannelInfoUpdated(const UserDataChannelInfo* modified_infos, size_t modified_infos_size,
const UserDataChannelInfo* deleted_infos, size_t deleted_infos_size) {}
virtual ~IDataChannelObserver() {}
};
} // namespace agora

View File

@@ -0,0 +1,99 @@
//
// Copyright (c) 2020 Agora.io. All rights reserved
// This program is confidential and proprietary to Agora.io.
// And may not be copied, reproduced, modified, disclosed to others, published
// or used, in whole or in part, without the express prior written permission
// of Agora.io.
#pragma once // NOLINT(build/header_guard)
#include "AgoraBase.h"
#include "AgoraRefPtr.h"
#include "IAgoraLog.h"
#include "NGIAgoraVideoFrame.h"
#include "NGIAgoraExtensionProvider.h"
namespace agora {
namespace rtc {
class IExtensionProvider;
/**
* Interface for handling agora extensions.
*/
class IExtensionControl {
public:
/**
* Agora Extension Capabilities.
*/
struct Capabilities {
/**
* Whether to support audio extensions.
*/
bool audio;
/**
* Whether to support video extensions.
*/
bool video;
};
/**
* Gets the capabilities of agora extensions.
*
* @param capabilities Supported extension capabilities.
*/
virtual void getCapabilities(Capabilities& capabilities) = 0;
/**
* Recycles internal frame memory with a specified Video frame type.
*
* The SDK automatically recycles deprecated video frames. However,
* you can still call this method to perform an immediate memory recycle.
* @param type Frame type to be recycled.
*/
virtual int recycleVideoCache() = 0;
/**
* This method dumps the content of the video frame to the specified file.
*
* @return
* - 0: The method call succeeds.
* - <0: The method call fails.
*/
virtual int dumpVideoFrame(agora_refptr<IVideoFrame> frame, const char* file) = 0;
/**
* Sets log file.
*
* @param level Logging level. See #commons::LOG_LEVEL.
* @param message Message to add to the log file.
* @return
* - 0: The method call succeeds.
* - <0: The method call fails.
*/
virtual int log(commons::LOG_LEVEL level, const char* message) = 0;
/**
* Post extension events to SDK.
*
* @param provider name of the provider
* @param extension name of the extension
* @param event_key key of the extension event
* @param event_json_str string of the extension event
* @return
* - 0: The method call succeeds.
* - <0: The method call fails.
*/
virtual int fireEvent(const char* provider, const char* extension, const char* event_key, const char* value) = 0;
/**
* Register provider to the SDK
* @param provider name of the provider
* @param instance instance of the provider
*/
virtual int registerProvider(const char* provider, agora_refptr<IExtensionProvider> instance) = 0;
protected:
virtual ~IExtensionControl() {}
};
} // namespace rtc
} // namespace agora

View File

@@ -0,0 +1,137 @@
//
// Agora SDK
//
// Copyright (c) 2021 Agora.io. All rights reserved.
//
#pragma once
#include "AgoraRefPtr.h"
#include "NGIAgoraMediaNode.h"
#include "AgoraExtensionVersion.h"
namespace agora {
namespace rtc {
class IExtensionControl;
/**
* Interfaces for Extension Provider
* User can implement these interfaces for providing their own media node implementations to SDK.
* Please refer to \ref agora::RefCountedObject to wrap your implementation so that it can be
* held by agora::agora_refptr.
* For example:
* class YourExtensionProvide: public IExtensionProvider {
* // Your Concrete implementaion
* };
*
* // Use agroa::RefCountedObject to provide RefCountInterface implementation for you implementation,
* // intantiate and wrap it with agora_refptr.
*
* agora_refptr<IExtensionProvider> provider = new RefCountedObject<YourExtensionProvide>(Arg1, Arg2, ...);
*
* You can instantiate your AudioFilter/VideoFilter/VideoSink in the same way.
*/
class IExtensionProvider : public RefCountInterface {
public:
enum EXTENSION_TYPE {
/**
* note: discarded, Don't use it anymore.
*/
AUDIO_FILTER,
/**
* note: discarded, Don't use it anymore.
*/
VIDEO_PRE_PROCESSING_FILTER,
VIDEO_POST_PROCESSING_FILTER,
AUDIO_SINK,
VIDEO_SINK,
/*
* Used to modify locally captured audio data to play, such as ear monitoring.
*/
AUDIO_RECORDING_LOCAL_PLAYBACK_FILTER = 10000,
/*
* Used to modify audio data after the local APM (3A).
*/
AUDIO_POST_PROCESSING_FILTER = 10001,
/*
* Used to modify received and decoded remote user audio data.
*/
AUDIO_REMOTE_USER_PLAYBACK_FILTER = 10002,
/*
* note: It is used internally by agora and does not support users other than agora.
*
* Used to modify the audio data of the sender's PCM source to take effect for sending and local playback.
*/
AUDIO_PCM_SOURCE_FILTER = 10003,
/*
* note: It is used internally by agora and does not support users other than agora.
*
* Used to Modifying the audio data of the sender's PCM source is only effect for the sending.
*/
AUDIO_PCM_SOURCE_SENDING_FILTER = 10004,
/*
* note: It is used internally by agora and does not support users other than agora.
*
* Used to Modifying the audio data of the sender's PCM source is only effect for the local playback.
*/
AUDIO_PCM_SOURCE_LOCAL_PLAYBACK_FILTER = 10005,
/*
* note: It is used internally by agora and does not support users other than agora.
*
* Used to modify local playback audio data after the remote audio mixed.
*/
AUDIO_REMOTE_MIXED_PLAYBACK_FILTER = 10006,
/*
* Used to modify video data betweent capturer and post-capture observer
*/
VIDEO_POST_CAPTURE_FILTER = 20001,
/*
* Used to modify video data betweent post-capture observer and preview
*/
VIDEO_PRE_PREVIEW_FILTER = 20002,
/*
* Used to modify video data betweent adapter and encoder
*/
VIDEO_PRE_ENCODER_FILTER = 20003,
UNKNOWN = 0xFFFF,
};
struct ExtensionMetaInfo {
EXTENSION_TYPE type;
const char* extension_name;
};
virtual void setExtensionControl(IExtensionControl* control) {}
virtual void enumerateExtensions(ExtensionMetaInfo* extension_list,
int& extension_count) {
(void) extension_list;
extension_count = 0;
}
virtual agora_refptr<IAudioFilter> createAudioFilter(const char* name) {
return NULL;
}
virtual agora_refptr<IExtensionVideoFilter> createVideoFilter(const char* name) {
return NULL;
}
virtual agora_refptr<IVideoSinkBase> createVideoSink(const char* name) {
return NULL;
}
virtual void setProperty(const char* key, const char* value) {}
protected:
virtual ~IExtensionProvider() {}
};
class IExtensionProviderV2 : public IExtensionProvider {
public:
virtual void getExtensionVersion(const char* extension_name, ExtensionVersion& version) = 0;
};
} // namespace rtc
} // namespace agora

View File

@@ -0,0 +1,944 @@
#pragma once
#include "AgoraRefPtr.h"
#include "AgoraBase.h"
#include "IAgoraLog.h"
#include "NGIAgoraVideoFrame.h"
#include "AgoraExtensionVersion.h"
#include <aosl/api/aosl_ref.h>
#ifndef OPTIONAL_PROCESSRESULT_SPECIFIER
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
#define OPTIONAL_PROCESSRESULT_SPECIFIER ProcessResult::
#else
#define OPTIONAL_PROCESSRESULT_SPECIFIER
#endif
#endif
namespace webrtc {
struct AudioFrameHandleInfo;
} // namespace webrtc
namespace agora {
namespace rtc {
/**
* The `IAudioFilterBase` class is the base class for audio filters. You can use this class to implement your own filter
* and add it to an audio track.
*/
class IAudioFilterBase : public RefCountInterface {
public:
// Return false if filter decide to drop the frame.
// Implementation should not change samples_per_channel_/sample_rate_hz_/num_channels_
// Implementation should just adapt data of audio frame.
/**
* Adapts the audio frame.
* @param inAudioFrame The reference to the audio frame that you want to adapt.
* @param adaptedFrame The reference to the adapted audio frame.
* @return
* - `true`: Success.
* - `false`: Failure. For example, the IAudiofilter object drops the audio frame.
*/
virtual bool adaptAudioFrame(const media::base::AudioPcmFrame& inAudioFrame,
media::base::AudioPcmFrame& adaptedFrame) = 0;
/**
* Get the sample rate supported by the audio filter, the framework will resample
* the audio data and then pass it to the audio filter.
* @return
* - 0: Audio data will not be resampled.
* - > 0: Audio data will be resampled to this sample rate.
*/
virtual int getPreferredSampleRate() = 0;
/**
* Get the channel number supported by the audio filter, the framework will resample
* the audio data and then pass it to the audio filter. If the user does not
* overwrite, resampling will not be done by default.
* @return
* - 0: Audio data will not be resampled.
* - > 0: Audio data will be resampled to this sample rate.
*/
virtual int getPreferredChannelNumbers() = 0;
protected:
~IAudioFilterBase() {}
};
/**
* The `IAudioFilter` class.
*
* This class is the intermediate node for audio, which reads audio frames from the underlying
* pipeline and writes audio frames back after adaptation.
*/
class IAudioFilter : public IAudioFilterBase {
public:
/**
* Enables or disables the audio filter.
* @param enable Whether to enable the audio filter:
* - `true`: Enable the audio filter.
* - `false`: Do not enable the audio filter.
*/
virtual void setEnabled(bool enable) = 0;
/**
* Checks whether the audio filter is enabled.
* @return
* - `true`: The audio filter is enabled.
* - `false`: The audio filter is not enabled.
*/
virtual bool isEnabled() const = 0;
/**
* Sets a private property in the `IAudioFilter` class.
*
* @param key The pointer to the property name.
* @param buf The pointer to the buffer of this private property.
* @param buf_size The buffer size of this private property.
* @return
* - The actual size of the private property, if the method call succeeds.
* - -1, if the method call fails.
*/
virtual int setProperty(const char* key, const void* buf, int buf_size) = 0;
/**
* Gets a private property in the `IAudioFilter` class.
*
* @param name The pointer to the property name.
* @param buf The pointer to the buffer of this private property.
* @param buf_size The buffer size of this private property.
* @return
* - The actual size of the private property, if the method call succeeds.
* - -1, if the method call fails.
*/
virtual int getProperty(const char* key, void* buf, int buf_size) const = 0;
/**
* Gets the name of the `IAudioFilter` class.
*
* @return
* - The name of the audio filter, if the method call succeeds.
* - An empty string, if the method call fails.
*/
virtual const char * getName() const = 0;
/**
* Get the sample rate supported by the audio filter, the framework will resample
* the audio data and then pass it to the audio filter. If the user does not
* overwrite, resampling will not be done by default.
* @return
* - 0: Audio data will not be resampled.
* - > 0: Audio data will be resampled to this sample rate.
*/
virtual int getPreferredSampleRate() { return 0; };
/**
* Get the channel number supported by the audio filter, the framework will resample
* the audio data and then pass it to the audio filter. If the user does not
* overwrite, resampling will not be done by default.
* @return
* - 0: Audio data will not be resampled.
* - > 0: Audio data will be resampled to this sample rate.
*/
virtual int getPreferredChannelNumbers() { return 0; };
protected:
~IAudioFilter() {}
};
class IAudioFilterV2 : public IAudioFilter {
public:
class Control : public RefCountInterface {
public:
/**
* @brief Post an event and notify the end users.
* @param key '\0' ended string that describes the key of the event
* @param value '\0' ended string that describes the value of the event
*/
virtual int postEvent(const char* key, const char* value) = 0;
/**
* @brief print log to the SDK.
* @param level Log level @ref agora::commons::LOG_LEVEL
* @param format log formatter string
* @param ... variadic arguments
*/
virtual void printLog(commons::LOG_LEVEL level, const char* format, ...) = 0;
};
public:
/**
* @brief AgoraSDK set IAudioFilterV2::Control to filter
* @param control IAudioFilterV2::Control
*/
virtual void setExtensionControl(agora::agora_refptr<IAudioFilterV2::Control> control) = 0;
};
/**
* The `IVideoFilterBase` class is the base class for video filters. You can use this class to implement your own filter
* and add the filter to a video track.
*/
class IVideoFilterBase : public RefCountInterface {
public:
/**
* Adapts the video frame.
*
* @param capturedFrame The reference to the captured video frame that you want to adapt.
* @param adaptedFrame The reference to the adapted video frame.
*
* @return
* - `true`: Success.
* - `false`: Failure, if, for example, the `IVideofilter` object drops the video frame.
*/
virtual bool adaptVideoFrame(const media::base::VideoFrame& capturedFrame,
media::base::VideoFrame& adaptedFrame) = 0;
};
// TODO(Bob): private inherit?
/**
* The IVideoFilter class.
*
* This class is the intermediate node for video, which contains both the video source and the video
* sink. It reads video frames from the underlying video pipeline and writes video frames back after
* adaptation.
*/
class IVideoFilter : public IVideoFilterBase {
public:
/**
* Enables or disables the video filter.
* @param enable Whether to enable the video filter:
* - `true`: (Default) Enable the video filter.
* - `false`: Do not enable the video filter. If the filter is disabled, frames will be passed without
* adaption.
*/
virtual void setEnabled(bool enable) {}
/**
* Checks whether the video filter is enabled.
* @return
* - `true`: The video filter is enabled.
* - `false`: The video filter is not enabled.
*/
virtual bool isEnabled() { return true; }
/**
* Sets a private property in the `IVideoFilter` class.
*
* @param key The pointer to the property name.
* @param buf The pointer to the buffer of this private property.
* @param buf_size The buffer size of this private property.
* @return
* - The actual size of the private property, if the method call succeeds.
* - -1, if the method call fails.
*/
virtual int setProperty(const char* key, const void* buf, size_t buf_size) { return -1; }
/**
* Gets a private property in the IVideoFilter class.
*
* @param key The pointer to the property name.
* @param buf The pointer to the buffer of this private property.
* @param buf_size The buffer size of this private property.
* @return
* - The actual size of the private property, if the method call succeeds.
* - -1, if the method call fails.
*/
virtual int getProperty(const char* key, void* buf, size_t buf_size) { return -1; }
/**
* This function is invoked right before data stream starts.
* Custom filter can override this function for initialization.
* @return
* - `true`: The initialization succeeds.
* - `false`: The initialization fails.
*/
virtual bool onDataStreamWillStart() { return true; }
/**
* This function is invoked right before data stream stops.
* Custom filter can override this function for deinitialization.
*/
virtual void onDataStreamWillStop() { }
/**
* This function indicates if the filter is for internal use.
* @note Do not override this function.
* @return
* - `true`: The filter is implemented by external users.
* - `false`: The filter is implemented by internal users.
*/
virtual bool isExternal() { return true; }
/**
* This function indicates if the filter is implemented by third-party providers.
* @note Do not override this function.
* @return
* - `true`: The filter is implemented by third-party providers.
* - `false`: otherwise.
*/
virtual bool isExtensionFilter() { return false; }
};
/**
* The IExtensionVideoFilter class.
*
* This class defines the interfaces that a external video extension provider can implement
* so as to be loaded by SDK as an "3rd party extension" for video pre- or post- processing.
*/
class IExtensionVideoFilter : public IVideoFilter {
public:
enum ProcessMode {
kSync, // Indicates that video frame data will be exchanged via "adaptVideoFrame"
kAsync, // Indicates that video frame data will be exchanged via "pendVideoFrame" & "deliverVideoFrame"
};
enum ProcessResult {
kSuccess, // Video frame data is successfully processed
kBypass, // Video frame data should bypass the current filter and flow to its successsors
kDrop, // Video Frame data should be discarded
};
/**
* The IExtensionVideoFilter::Control class.
*
* This class defines the interfaces that the extension filter can leverage to interact with the SDK.
* The "IExtensionVideoFilter::Control" object will be passed to the filter when SDK invoke the filter's
* "start" interface.
*/
class Control : public RefCountInterface {
public:
/**
* @brief Filter can invoke this function to deliver the processed frame to SDK if the Process Mode is
* designated as "kAsync" by the filter via "getProcessMode".
* @param frame the processed video frame
* @return see @ref ProcessResult
*/
virtual ProcessResult deliverVideoFrame(agora::agora_refptr<IVideoFrame> frame) = 0;
/**
* @brief Filter can invoke this function to get the IVideoFrameMemoryPool object if a new IVideoFrame
* data object is needed.
*/
virtual agora::agora_refptr<IVideoFrameMemoryPool> getMemoryPool() = 0;
/**
* @brief Post an event and notify the end users.
* @param key '\0' ended string that describes the key of the event
* @param value '\0' ended string that describes the value of the event
*/
virtual int postEvent(const char* key, const char* value) = 0;
/**
* @brief print log to the SDK.
* @param level Log level @ref agora::commons::LOG_LEVEL
* @param format log formatter string
* @param ... variadic arguments
*/
virtual void printLog(commons::LOG_LEVEL level, const char* format, ...) = 0;
/**
* @brief Ask SDK to disable the current filter if a fatal error is detected
* @param error error code
* @param msg error message
*/
virtual void disableMe(int error, const char* msg) = 0;
};
/**
* @brief SDK will invoke this API first to get the filter's requested process mode @ref ProcessMode
* @param mode [out] filter assign its desired the process mode @ref ProcessMode
* @param independent_thread deprecated. SDK will ignore this parameter.
* @note If the filter implementation is not thread sensitive, we recommend to set the boolean to "false" to reduce thread context
* switching.
*/
virtual void getProcessMode(ProcessMode& mode, bool& independent_thread) = 0;
/**
* @brief SDK will invoke this API before feeding video frame data to the filter. Filter can perform its initialization/preparation job
* in this step.
*
* @param control object to @ref IExtensionFilter::Control that pass to the filter which can be used for future interaction with the SDK
* @return error code
*/
virtual int start(agora::agora_refptr<Control> control) = 0;
/**
* @brief SDK will invoke this API when the data stream is about to stop. Filter can perform cleanup jobs in this step
*
* @return error code
*/
virtual int stop() = 0;
/**
* @brief SDK will invoke this API every time before sending data to the filter. Filter can desigante the type @ref VideoFrameInfo::Type
* and format @ref MemPixelBuffer::Format of the next frame. SDK will then try to perform type / format conversion before sending data to
* the filter.
*
* @param type requested type of the next frame
* @param format requested formant of the next frame
*/
virtual void getVideoFormatWanted(VideoFrameData::Type& type, RawPixelBuffer::Format& format) = 0;
/**
* @brief SDK will invoke this API to send video frame to the filter if process mode is "Async". Filter invokes control's "deliverFrame"
* to send back the frame after processing.
*
* @param frame frame pending for processing
*/
virtual ProcessResult pendVideoFrame(agora::agora_refptr<IVideoFrame> frame) {
return OPTIONAL_PROCESSRESULT_SPECIFIER kBypass;
}
/**
* @brief SDK will invoke this API to send video frame to the filter if process mode is "Sync".
*
* @param frame frame pending for processing
*/
virtual ProcessResult adaptVideoFrame(agora::agora_refptr<IVideoFrame> in, agora::agora_refptr<IVideoFrame>& out) {
return OPTIONAL_PROCESSRESULT_SPECIFIER kBypass;
}
/* Occurs each time needs to get rotation apply.
*
* @return Determines whether to rotate.
* - true: need to rotate.
* - false: no rotate.
*/
virtual bool getRotationApplied() { return false; }
// NOTE: The following two interfaces should never be overriden!
virtual bool isExtensionFilter() { return true; }
virtual bool adaptVideoFrame(
const media::base::VideoFrame& capturedFrame,
media::base::VideoFrame& adaptedFrame) {
return -ERR_NOT_SUPPORTED;
}
};
class ILipSyncFilter : public RefCountInterface {
public:
enum ProcessResult {
kSuccess, // Video frame data is successfully processed
kBypass, // Video frame data should bypass the current filter and flow to its successsors
kDrop, // Video Frame data should be discarded
};
class Control : public RefCountInterface {
public:
/**
* @brief Post an event and notify the end users.
* @param key '\0' ended string that describes the key of the event
* @param value '\0' ended string that describes the value of the event
*/
virtual int postEvent(const char* key, const char* value) = 0;
/**
* @brief print log to the SDK.
* @param level Log level @ref agora::commons::LOG_LEVEL
* @param format log formatter string
* @param ... variadic arguments
*/
virtual void printLog(commons::LOG_LEVEL level, const char* format, ...) = 0;
/**
* @brief Ask SDK to disable the current filter if a fatal error is detected
* @param error error code
* @param msg error message
*/
virtual void disableMe(int error, const char* msg) = 0;
/**
* @brief report counter to the SDK.
* @param counter_id counter id
* @param value counter value
*/
virtual void ReportCounter(int32_t counter_id, int32_t value) = 0;
/**
* @brief get stats to the SDK.
* @param counter_id counter id
*/
virtual int GetStats(int32_t counter_id) = 0;
};
virtual int start(agora::agora_refptr<Control> control) = 0;
virtual int stop() = 0;
virtual int setProperty(const char* key, const void* buf, size_t buf_size) { return -1; }
/**
* Convert the audio frame to face info.
* @param inAudioFrame The reference to the audio frame that you want to convert.
* @param outFaceInfo The reference to the face info.
* @return see @ref ProcessResult
*/
virtual ProcessResult convertAudioFrameToFaceInfo(const agora::media::base::AudioPcmFrame& inAudioFrame, char* outFaceInfo) {
return kBypass;
}
};
/**
* The `IVideoSinkBase` class is the base class for the custom video sink.
*/
class IVideoSinkBase : public RefCountInterface {
public:
/**
* Sets a private property in the `IVideoFilter` class.
*
* @param key The pointer to the property name.
* @param buf The pointer to the buffer of this private property.
* @param buf_size The buffer size of this private property.
* @return
* - The actual size of the private property, if the method call succeeds.
* - -1, if the method call fails.
*/
virtual int setProperty(const char* key, const void* buf, int buf_size) { return -1; }
/**
* Gets a private property in the `IVideoFilter` class.
*
* @param key The pointer to the property name.
* @param buf The pointer to the buffer of this private property.
* @param buf_size The buffer size of this private property.
* @return
* - The actual size of the private property, if the method call succeeds.
* - -1, if the method call fails.
*/
virtual int getProperty(const char* key, void* buf, int buf_size) { return -1; }
/**
* Occurs when the `IVideoSinkBase` object receives the video frame.
* @param videoFrame The reference to the video frame.
*/
virtual int onFrame(const media::base::VideoFrame& videoFrame) = 0;
/**
* Used internally to distinguish between external and internal sinks.
* External application should not override this interface.
*/
virtual bool isExternalSink() { return true; }
/**
* This function is invoked right before data stream starts.
* Custom sink can override this function for initialization.
* @return
* - `true`, if initialization succeeds.
* - `false`, if initialization fails.
*/
virtual bool onDataStreamWillStart() { return true; }
/**
* This function is invoked right before data stream stops.
* Custom sink can override this function for deinitialization.
*/
virtual void onDataStreamWillStop() { }
/**
* Whether to mirror the video frame.
* @return
* - true: mirror the video frame.
* - false: do not mirror the video frame.
*/
virtual bool applyMirror() { return false; }
/**
* Whether to rotate the video frame.
* @return
* - true: rotate the video frame.
* - false: do not rotate the video frame.
*/
virtual bool applyRotation() { return false; }
};
class IMediaExtensionObserver : public RefCountInterface {
public:
virtual ~IMediaExtensionObserver() {}
virtual void onEventWithContext(const ExtensionContext& context, const char* key, const char* json_value) {}
virtual void onExtensionStoppedWithContext(const ExtensionContext& context) {}
virtual void onExtensionStartedWithContext(const ExtensionContext& context) {}
virtual void onExtensionErrorWithContext(const ExtensionContext& context, int error, const char* message) {}
};
/**
* The IAudioPcmDataSender class.
*
* In scenarios involving custom audio source, you can use the `IAudioPcmDataSender` class to send PCM audio data directly to the audio track. If the audio track is disabled, the sent audio data is automatically discarded.
*/
class IAudioPcmDataSender : public RefCountInterface {
public:
/**
* Sends the PCM audio data to the local audio track.
*
* @param audio_data The PCM audio data to be sent.
* @param samples_per_channel The number of audio samples in 10 ms for each audio channel.
* @param bytes_per_sample The number of bytes in each sample.
* @param number_of_channels The number of audio channels.
* @param sample_rate The sample rate (Hz). The minimum value is 8000.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int sendAudioPcmData(
const void* audio_data, uint32_t capture_timestamp, int64_t presentation_ms,
const size_t samples_per_channel, // for 10ms Data, number_of_samples * 100 = sample_rate
const agora::rtc::BYTES_PER_SAMPLE bytes_per_sample, // 2
const size_t number_of_channels,
const uint32_t sample_rate, aosl_ref_t ares = AOSL_REF_INVALID) = 0; // sample_rate > 8000)
protected:
~IAudioPcmDataSender() {}
};
/**
* The `IAudioEncodedFrameSender` class.
*
* In scenarios involving custom audio source, you can use the `IAudioEncodedFrameSender` class to
* send encoded audio data directly to the audio track. If the track is disabled, the sent audio
* data will be automatically discarded.
*/
class IAudioEncodedFrameSender : public RefCountInterface {
public:
/**
* Sends the encoded audio frame to the local audio track.
*
* @param payload_data The pointer to the payload data.
* @param payload_size The payload size.
* @param audioFrameInfo The reference to the information of the audio frame:
* \ref agora::rtc::EncodedAudioFrameInfo "EncodedAudioFrameInfo".
*
* @return
* - `true`: Success.
* - `false`: Failure.
*/
virtual bool sendEncodedAudioFrame(const uint8_t* payload_data, size_t payload_size,
const EncodedAudioFrameInfo& audioFrameInfo, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
protected:
~IAudioEncodedFrameSender() {}
};
class IAudioEncodedFrameReceiver {
public:
/**
* Occurs when the track receives an audio encodeed frame packet.
*
* @param packet The pointer to the audio packet.
* @param length The length of the packet.
* @param info The packet info.
*
*/
virtual bool onEncodedAudioFrameReceived (
const uint8_t *packet, size_t length, const media::base::AudioEncodedFrameInfo& info) = 0;
virtual ~IAudioEncodedFrameReceiver() {}
};
/**
* The IMediaPacketReceiver class. You can register a receiver in remote audio or video tracks to trigger
* callbacks when RTP/UDP packets are received.
*/
class IMediaPacketReceiver {
public:
/**
* Occurs when the track receives a media packet.
*
* @param packet The pointer to the media packet.
* @param length The length of the packet.
* @param options The packet info.
*
*/
virtual bool onMediaPacketReceived(
const uint8_t *packet, size_t length, const agora::media::base::PacketOptions& options) = 0;
virtual ~IMediaPacketReceiver() {}
};
/**
* The IMediaControlPacketReceiver class.
*
* You can register a receiver in audio or video tracks to trigger callbacks
* when RTCP/UDP packets are received.
*/
class IMediaControlPacketReceiver {
public:
/**
* Occurs when the track receives media control packet.
*
* @param packet The pointer to the media packet.
* @param length The length of the packet.
*
*/
virtual bool onMediaControlPacketReceived(uid_t uid, const uint8_t *packet, size_t length) = 0;
virtual ~IMediaControlPacketReceiver() {}
};
/**
* The `IMediaPacketSender` class.
*
* You can use the `IMediaPacketSender` class to create a LocalVideoTrack or LocalAudioTrack,
* and then send media packets directly to the track. The media packets are RTP/UDP packets that contain
* media payload. If the track is disabled, the packets will be automatically discarded.
*/
class IMediaPacketSender : public RefCountInterface {
public:
/**
* Sends the frame packet to the local track.
*
* @param packet The pointer to the packet.
* @param length The packet size.
* @param options The packet information: {@link media::base::PacketOptions PacketOptions}.
*
* @return
* - `true`: Success.
* - `false`: Failure.
*/
virtual int sendMediaPacket(const uint8_t *packet, size_t length,
const media::base::PacketOptions &options, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
protected:
~IMediaPacketSender() {}
};
/**
* The `IMediaControlPacketSender` class.
*
* You can get the `IMediaControlPacketSender` class object from a video track or audio track,
* and then send media control packets directly. The media control packets are RTCP/UDP packets that contain
* media control payload. If the track is disabled, the packets will be automatically discarded.
*/
class IMediaControlPacketSender {
public:
/**
* Sends the media control packet to a specified user.
* Currently, we only support sending packets through video tracks.
*
* @param userId ID of the user to send the packet to.
* @param packet The pointer to the packet.
* @param length The packet size.
*
* @return
* - `true`: Success.
* - `false`: Failure.
*/
virtual int sendPeerMediaControlPacket(media::base::user_id_t userId,
const uint8_t *packet,
size_t length, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Sends the media transport control packet to all users.
* Currently, we only support sending packets through video tracks.
* @param packet The pointer to the packet.
* @param length The packet size.
*
* @return
* - `true`: Success.
* - `false`: Failure.
*/
virtual int sendBroadcastMediaControlPacket(const uint8_t *packet, size_t length, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
virtual ~IMediaControlPacketSender() {}
};
/**
* The `IAudioSinkBase` class is the base class for the audio sink. You can use this class to implement your own sink
* and add the sink to an audio track.
*/
class IAudioSinkBase : public RefCountInterface {
public:
/** Gets the audio frame.
*
* @param audioframe {@link media::base::AudioPcmFrame AudioPcmFrame}
* @return
* - `true`: Success.
* - `false`: Failure.
*/
virtual bool onAudioFrame(const media::base::AudioPcmFrame& audioFrame) = 0;
protected:
~IAudioSinkBase() {}
};
/**
* The `IVideoFrameSender` class.
*
* In scenarios involving custom video sources, you can use this class to send the video
* data directly to a video track. If the video track is disabled, the sent data will
* be automatically discarded.
*/
class IVideoFrameSender : public RefCountInterface {
public:
/**
* Sends the video frame to the video track.
*
* @param videoFrame The reference to the video frame to send.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int sendVideoFrame(const media::base::ExternalVideoFrame& videoFrame, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
protected:
~IVideoFrameSender() {}
};
/**
* The `IVideoEncodedImageSender` class.
*
* In scenarios involving custom video sources, you can use this class to send the encoded video data
* directly to the video track. If the video track is disabled, the sent video image will be
* automatically discarded.
*/
class IVideoEncodedImageSender : public RefCountInterface {
public:
/**
* Sends the encoded video image to the video track.
* @param imageBuffer The video buffer.
* @param length The data length of the video data.
* @param videoEncodedFrameInfo The reference to the information of the encoded video frame:
* {@link EncodedVideoFrameInfo}.
*
* @return
* - `true`: Success.
* - `false`: Failure.
*/
virtual bool sendEncodedVideoImage(const uint8_t* imageBuffer, size_t length,
const EncodedVideoFrameInfo& videoEncodedFrameInfo, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
protected:
~IVideoEncodedImageSender() {}
};
/**
* The IVideoBeautyFilter class.
*/
class IVideoBeautyFilter : public IVideoFilter {
public:
/**
* The video image enhancement options.
*/
struct BeautyOptions {
/**
* The lightening contrast level.
*/
enum LIGHTENING_CONTRAST_LEVEL {
/**
* 0: Low contrast level.
*/
LIGHTENING_CONTRAST_LOW = 0,
/**
* (Default) Normal contrast level.
*/
LIGHTENING_CONTRAST_NORMAL,
/**
* High contrast level.
*/
LIGHTENING_CONTRAST_HIGH
};
/**
* The contrast level, usually used with {@link lighteningLevel} to brighten the video:
* #LIGHTENING_CONTRAST_LEVEL.
*/
LIGHTENING_CONTRAST_LEVEL lighteningContrastLevel;
/**
* The brightness level. The value ranges from 0.0 (original) to 1.0.
*/
float lighteningLevel;
/**
* The sharpness level. The value ranges from 0.0 (original) to 1.0. This parameter is usually
* used to remove blemishes.
*/
float smoothnessLevel;
/**
* The redness level. The value ranges from 0.0 (original) to 1.0. This parameter adjusts the
* red saturation level.
*/
float rednessLevel;
BeautyOptions(LIGHTENING_CONTRAST_LEVEL contrastLevel, float lightening, float smoothness,
float redness)
: lighteningContrastLevel(contrastLevel),
lighteningLevel(lightening),
smoothnessLevel(smoothness),
rednessLevel(redness) {}
BeautyOptions()
: lighteningContrastLevel(LIGHTENING_CONTRAST_NORMAL),
lighteningLevel(0),
smoothnessLevel(0),
rednessLevel(0) {}
};
/**
* Sets the image enhancement options.
* @param enabled Whether to enable image enhancement.
* - `true`: Enable image enhancement.
* - `false`: Do not enable image enhancement.
* @param options The image enhancement options: BeautyOptions.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setBeautyEffectOptions(bool enabled, BeautyOptions options) = 0;
};
/**
* The `IVideoRenderer` class.
*/
class IVideoRenderer : public IVideoSinkBase {
public:
/**
* Sets the render mode.
* @param renderMode The video render mode.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setRenderMode(media::base::RENDER_MODE_TYPE renderMode, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Sets the render mode of the view.
* @param view the view to set render mode.
* @param renderMode The video render mode.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setRenderMode(void* view, media::base::RENDER_MODE_TYPE renderMode, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Sets whether to mirror the video.
* @param mirror Whether to mirror the video:
* - `true`: Mirror the video.
* - `false`: Do not mirror the video.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setMirror(bool mirror, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Sets whether to mirror the video.
* @param view the view to set mirror mode.
* @param mirror Whether to mirror the video:
* - `true`: Mirror the video.
* - `false`: Do not mirror the video.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setMirror(void* view, bool mirror, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Sets the video display window.
* @param view The pointer to the video display window.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setView(void* view, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Sets the video display window.
* @param view The pointer to the video display window.
* @param cropArea (Optional) Sets the relative location of the region to show. See Rectangle.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int addView(void* view, const Rectangle& cropArea, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Stops rendering the video view on the window.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int unsetView(aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* remove rendering the video view on the window.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int removeView(void* view) = 0;
};
static const int kDeviceIdSize = 128;
class IVideoTrack;
/**
* The `IVideoFrameTransceiver` class.
*/
class IVideoFrameTransceiver : public RefCountInterface {
public:
virtual int getTranscodingDelayMs() = 0;
virtual int addVideoTrack(agora_refptr<IVideoTrack> track, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
virtual int removeVideoTrack(agora_refptr<IVideoTrack> track, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
};
}
}

View File

@@ -0,0 +1,264 @@
//
// Agora SDK
//
// Copyright (c) 2019 Agora.io. All rights reserved.
//
#pragma once // NOLINT(build/header_guard)
#include "AgoraBase.h"
#include <aosl/api/cpp/aosl_ares_class.h>
namespace agora {
namespace rtc {
class IAudioPcmDataSender;
class IAudioEncodedFrameSender;
class IRemoteAudioMixerSource;
class ICameraCapturer;
class IScreenCapturer;
class IVideoMixerSource;
class IVideoFrameTransceiver;
class IVideoFrameSender;
class IVideoRenderer;
class IVideoFilter;
class IAudioFilter;
class IVideoSinkBase;
class IVideoEncodedImageSender;
class IMediaPlayerSource;
class IMediaPacketSender;
class IMediaStreamingSource;
class IScreenCapturer2;
class IMediaRecorder2;
/**
* The `IMediaNodeFactory` class.
*/
class IMediaNodeFactory : public RefCountInterface {
public:
/**
* Creates a PCM audio data sender.
*
* This method creates an `IAudioPcmDataSender` object, which can be used by \ref
* agora::base::IAgoraService::createCustomAudioTrack(agora_refptr< rtc::IAudioPcmDataSender >
* audioSource) "createCustomAudioTrack" to send PCM audio data.
*
* @return
* - The pointer to \ref agora::rtc::IAudioPcmDataSender "IAudioPcmDataSender": Success.
* - A null pointer: Failure.
*/
virtual agora_refptr<IAudioPcmDataSender> createAudioPcmDataSender() = 0;
/**
* Creates an encoded audio data sender.
*
* This method creates an IAudioEncodedFrameSender object, which can be used by \ref
* agora::base::IAgoraService::createCustomAudioTrack(agora_refptr< rtc::IAudioEncodedFrameSender
* > audioSource, TMixMode mixMode) "createCustomAudioTrack" to send encoded audio data.
*
* @return
* - The pointer to IAudioEncodedFrameSender: Success.
* - A null pointer: Failure.
*/
virtual agora_refptr<IAudioEncodedFrameSender> createAudioEncodedFrameSender() = 0;
/**
* Creates a camera capturer.
*
* Once a camera capturer object is created, you can use the video data captured by the camera as
* the custom video source.
*
* @return
* - The pointer to ICameraCapturer: Success.
* - A null pointer: Failure.
*/
virtual agora_refptr<ICameraCapturer> createCameraCapturer() = 0;
#if !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IPHONE)
/**
* Creates a screen capturer.
*
* Once a screen capturer object is created, you can use the screen video data as the custom video
* source.
*
* @return
* - The pointer to IScreenCapturer: Success.
* - A null pointer: Failure.
*/
virtual agora_refptr<IScreenCapturer> createScreenCapturer() = 0;
#endif
/**
* Creates a video mixer.
*
* Once a video mixer object is created, you can use the video mixer data as the custom video
* source.
*
* @return
* - The pointer to IVideoMixerSource: Success.
* - A null pointer: Failure.
*/
virtual agora_refptr<IVideoMixerSource> createVideoMixer() = 0;
/**
* Creates a video transceiver.
*
* Once a video transceiver object is created, you can use the video transceiver data as the
* custom video source.
*
* @return
* - The pointer to IVideoFrameTransceiver: Success.
* - A null pointer: Failure.
*/
virtual agora_refptr<IVideoFrameTransceiver> createVideoFrameTransceiver() = 0;
/**
* Creates a video frame sender.
*
* This method creates an `IVideoFrameSender` object, which can be used by \ref
* agora::base::IAgoraService::createCustomVideoTrack(agora_refptr<rtc::IVideoFrameSender>
* videoSource) "createCustomVideoTrack" to send the custom video data.
*
* @return
* - The pointer to \ref agora::rtc::IVideoFrameSender "IVideoFrameSender": Success.
* - A null pointer: Failure.
*/
virtual agora_refptr<IVideoFrameSender> createVideoFrameSender() = 0;
/**
* Creates an encoded video image sender.
*
* This method creates an `IVideoEncodedImageSender` object, which can be used by \ref
* agora::base::IAgoraService::createCustomVideoTrack(agora_refptr<rtc::IVideoEncodedImageSender>
* videoSource, SenderOptions& options) "createCustomVideoTrack" to send the encoded video data.
*
* @return
* - The pointer to `IVideoEncodedImageSender`: Success.
* - A null pointer: Failure.
*/
virtual agora_refptr<IVideoEncodedImageSender> createVideoEncodedImageSender() = 0;
/**
* Creates a built-in video renderer.
*
* @param view The video window view.
* @return
* - The pointer to `IVideoRenderer`: Success.
* - A null pointer: Failure.
*
*/
virtual agora_refptr<IVideoRenderer> createVideoRenderer() = 0;
/**
* Creates an audio filter for the extension.
*
* This method creates an `IAudioFilter` object, which can be used to filter the audio data from
* the inside extension.
*
* @param provider_name provider name string.
* @param extension_name extension name string.
* @return
* - The pointer to IAudioFilter: Success.
* - A null pointer: Failure.
*/
virtual agora_refptr<IAudioFilter> createAudioFilter(const char* provider_name,
const char* extension_name) = 0;
/**
* Creates a video filter for the extension.
*
* This method creates an `IVideoFilter` object, which can be used to filter the video from inside
* extension.
*
* @param provider_name provider name string.
* @param extension_name extension name string.
* @return
* - The pointer to IVideoFilter: Success.
* - A null pointer: Failure.
*/
virtual agora_refptr<IVideoFilter> createVideoFilter(const char* provider_name,
const char* extension_name) = 0;
/**
* Creates a video sink for the extension.
*
* This method creates an IVideoSinkBase object, which can be used to receive the video from the
* inside extension.
*
* @param provider_name provider name string.
* @param extension_name extension name string.
* @return
* - The pointer to IVideoSinkBase: Success.
* - A null pointer: Failure.
*/
virtual agora_refptr<IVideoSinkBase> createVideoSink(const char* provider_name,
const char* extension_name) = 0;
/**
* Creates a media player source object and returns the pointer.
*
* @param type The type of media player source you want to create.
*
* @return
* - The pointer to \ref rtc::IMediaPlayerSource "IMediaPlayerSource", if the method call
* succeeds.
* - A null pointer: Failure.
*/
virtual agora_refptr<IMediaPlayerSource> createMediaPlayerSource(
media::base::MEDIA_PLAYER_SOURCE_TYPE type =
agora::media::base::MEDIA_PLAYER_SOURCE_DEFAULT) = 0;
/**
* @brief Creates a media streaming source object and returns the pointer.
*
* @param type The type of media streaming source you want to create.
*
* @return
* - The pointer to \ref rtc::IMediaStreamingSource "IMediaStreamingSource", if the method call
* succeeds.
* - A null pointer: Failure.
*/
virtual agora_refptr<IMediaStreamingSource> createMediaStreamingSource() = 0;
/**
* Creates a media packet sender object and returns the pointer.
*
* @return
* - The pointer to \ref rtc::IMediaPacketSender "IMediaPacketSender", if the method call
* succeeds.
* - A null pointer: Failure.
*/
virtual agora_refptr<IMediaPacketSender> createMediaPacketSender() = 0;
virtual agora_refptr<IMediaRecorder2> createMediaRecorder() = 0;
#if defined(__ANDROID__) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)
/**
* Creates screen capture source extension with given provider&extension names
* @param provider_name provider name string.
* @param extension_name extension name string.
* @return
* - The pointer to IScreenCapturer: Success.
* - A null pointer: Failure.
*/
virtual agora_refptr<IScreenCapturer2> createScreenCapturer2(const char* provider_name,
const char* extension_name) = 0;
#else
/**
* Creates screen capture source extension with given provider&extension names
* @param provider_name provider name string.
* @param extension_name extension name string.
* @return
* - The pointer to IScreenCapturer: Success.
* - A null pointer: Failure.
*/
virtual agora_refptr<IScreenCapturer> createScreenCapturer(const char* provider_name,
const char* extension_name) = 0;
#endif
protected:
~IMediaNodeFactory() {}
};
} // namespace rtc
} // namespace agora

View File

@@ -0,0 +1,45 @@
//
// Agora SDK
//
// Copyright (c) 2020 Agora.io. All rights reserved.
//
#pragma once
#include "AgoraRefPtr.h"
#include <aosl/api/cpp/aosl_ares_class.h>
namespace agora {
namespace rtc {
class IRemoteAudioTrack;
/**
* The IRemoteAudioMixerSource class abstracts a multi-in-single-out audio source which receives audio
* streams from multiple remote audio tracks and generate mixed audio stream in user defined output
* format.
*/
class IRemoteAudioMixerSource : public RefCountInterface {
public:
virtual ~IRemoteAudioMixerSource() {}
/**
* Add a audio track for mixing. Automatically starts mixing if add audio track
* @param track The instance of the audio track that you want mixer to receive its audio stream.
*/
virtual int addAudioTrack(agora_refptr<IRemoteAudioTrack> track, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Remove a audio track for mixing. Automatically stops the mixed stream if all audio tracks are removed
* @param track The instance of the audio track that you want to remove from the mixer.
*/
virtual int removeAudioTrack(agora_refptr<IRemoteAudioTrack> track, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Gets the delay time for mix.
*/
virtual int getMixDelay() const = 0;
};
} // namespace rtc
} // namespace agora

View File

@@ -0,0 +1,859 @@
//
// Agora SDK
//
// Created by Sting Feng in 2018-01.
// Copyright (c) 2018 Agora.io. All rights reserved.
//
#pragma once // NOLINT(build/header_guard)
#include "AgoraBase.h"
#include "time_utils.h"
#include <aosl/api/cpp/aosl_ares_class.h>
namespace agora {
namespace rtc {
class IAudioEncodedFrameSender;
class IRtcConnectionObserver;
class INetworkObserver;
class IRtcConnection;
class IVideoEncodedImageSender;
class ILocalUser;
/**
* The information of an RTC Connection.
*/
struct TConnectionInfo {
/**
* The ID of the RTC Connection.
*/
conn_id_t id;
/**
* The ID of the channel. If you have not called \ref agora::rtc::IRtcConnection::connect "connect", this member is `NULL`.
*/
util::AString channelId;
/**
* The connection state: #CONNECTION_STATE_TYPE.
*/
CONNECTION_STATE_TYPE state;
/**
* The ID of the local user.
*/
util::AString localUserId;
/**
* Internal use only.
*/
uid_t internalUid;
int proxyType;
util::AString connectionIp;
TConnectionInfo() : id(-1), state(CONNECTION_STATE_DISCONNECTED), internalUid(0), proxyType(0) {}
};
struct TConnectSettings {
/**
* The app ID.
*/
const char* token;
/**
The channel name. It must be in the string format and not exceed 64 bytes in length. Supported character scopes are:
* - All lowercase English letters: a to z.
* - All uppercase English letters: A to Z.
* - All numeric characters: 0 to 9.
* - The space character.
* - Punctuation characters and other symbols, including: "!", "#", "$", "%", "&", "(", ")", "+",
* "-", ":", ";", "<", "=",
* ".", ">", "?", "@", "[", "]", "^", "_", " {", "}", "|", "~", ","
*/
const char* channelId;
/**
The ID of the local user. If you do not specify a user ID or set `userId` as `null`,
* the SDK returns a user ID in the \ref IRtcConnectionObserver::onConnected "onConnected"
* callback. Your app must record and maintain the `userId` since the SDK does not do so.
*/
user_id_t userId;
/*Reserved for future use*/
const char* info;
/*
App can provide a app defined start time to trace some events like connect cost , first video, etc.
*/
agora::Optional<int64_t> appDefinedStartTimeMs;
};
/**
* Configurations for an RTC connection.
*
* Set these configurations when calling \ref agora::base::IAgoraService::createRtcConnection "createRtcConnection".
*/
struct RtcConnectionConfiguration {
/**
* Whether to subscribe to all audio tracks automatically.
* - `true`: (Default) Subscribe to all audio tracks automatically.
* - `false`: Do not subscribe to any audio track automatically.
*/
bool autoSubscribeAudio;
/**
* Whether to subscribe to all video tracks automatically.
* - `true`: (Default) Subscribe to all video tracks automatically.
* - `false`: Do not subscribe to any video track automatically.
*/
bool autoSubscribeVideo;
/**
* Whether to enable audio recording or playout.
* - `true`: Enables audio recording or playout. Use this option when you publish and mix audio tracks, or subscribe to one or multiple audio tracks and play audio.
* - `false`: Disables audio recording or playout. Use this option when you publish external audio frames without audio mixing, or you do not need audio devices to play audio.
*/
bool enableAudioRecordingOrPlayout;
/**
* The maximum sending bitrate.
*/
int maxSendBitrate;
/**
* The minimum port.
*/
int minPort;
/**
* The maximum port.
*/
int maxPort;
/**
* The user role. For details, see #CLIENT_ROLE_TYPE. The default user role is `CLIENT_ROLE_AUDIENCE`.
*/
CLIENT_ROLE_TYPE clientRoleType;
/** The channel profile. For details, see #CHANNEL_PROFILE_TYPE. The default channel profile is `CHANNEL_PROFILE_LIVE_BROADCASTING`.
*/
CHANNEL_PROFILE_TYPE channelProfile;
/**
* Determines whether to receive audio encoded frame or not.
*/
bool audioRecvEncodedFrame;
/**
* Determines whether to receive audio media packet or not.
*/
bool audioRecvMediaPacket;
/**
* Determines whether to receive video media packet or not.
*/
bool videoRecvMediaPacket;
/**
* This mode is only used for audience. In PK mode, client might join one
* channel as broadcaster, and join another channel as interactive audience to
* achieve low lentancy and smooth video from remote user.
* - true: Enable low lentancy and smooth video when joining as an audience.
* - false: (Default) Use default settings for audience role.
*/
bool isInteractiveAudience;
/**
* Indicates data channel only.
*/
bool isDataChannelOnly;
RtcConnectionConfiguration()
: autoSubscribeAudio(true),
autoSubscribeVideo(true),
enableAudioRecordingOrPlayout(true),
maxSendBitrate(-1),
minPort(0),
maxPort(0),
clientRoleType(CLIENT_ROLE_AUDIENCE),
channelProfile(CHANNEL_PROFILE_LIVE_BROADCASTING),
audioRecvEncodedFrame(false),
audioRecvMediaPacket(false),
videoRecvMediaPacket(false),
isInteractiveAudience(false),
isDataChannelOnly(false) {}
};
/**
* The `IRtcConnection` class.
*
* You can use this class for managing the connection between your app and an Agora Channel.
*
* Once connected, your app gets an `AgoraLocalUser` object for publishing and subscribing to media streams in the Agora Channel.
*
* Connecting to a channel is done asynchronously, and your app can listen for the connection states or events through `IRtcConnectionObserver`.
* `IRtcConnection` also monitors remote users in the channel. The SDK notifies your app when a remote user joins or leaves the channel.
*/
class IRtcConnection : public RefCountInterface {
protected:
~IRtcConnection() {}
public:
/**
* Connects to an Agora channel.
*
* When the method call succeeds, the connection state changes from `CONNECTION_STATE_DISCONNECTED(1)` to
* `CONNECTION_STATE_CONNECTING(2)`.
*
* Depending on the whether the connection succeeds or not, the
* connection state changes to either `CONNECTION_STATE_CONNECTED(3)` or `CONNECTION_STATE_FAILED(5)`. The SDK also triggers `onConnected` or `onDisconnected` to notify you of the state change.
*
* @param token The app ID.
* @param channelId The channel name. It must be in the string format and not exceed 64 bytes in length. Supported character scopes are:
* - All lowercase English letters: a to z.
* - All uppercase English letters: A to Z.
* - All numeric characters: 0 to 9.
* - The space character.
* - Punctuation characters and other symbols, including: "!", "#", "$", "%", "&", "(", ")", "+",
* "-", ":", ";", "<", "=",
* ".", ">", "?", "@", "[", "]", "^", "_", " {", "}", "|", "~", ","
* @param userId The ID of the local user. If you do not specify a user ID or set `userId` as `null`,
* the SDK returns a user ID in the \ref IRtcConnectionObserver::onConnected "onConnected"
* callback. Your app must record and maintain the `userId` since the SDK does not do so.
* @return
* - 0: Success.
* - < 0: Failure.
* - -2(ERR_INVALID_ARGUMENT): The argument that you pass is invalid.
* - -8(ERR_INVALID_STATE): The current connection state is not CONNECTION_STATE_DISCONNECTED(1).
*/
virtual int connect(const char* token, const char* channelId, const char* info, user_id_t userId, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Connects to an Agora channel.
*
* When the method call succeeds, the connection state changes from `CONNECTION_STATE_DISCONNECTED(1)` to
* `CONNECTION_STATE_CONNECTING(2)`.
*
* Depending on the whether the connection succeeds or not, the
* connection state changes to either `CONNECTION_STATE_CONNECTED(3)` or `CONNECTION_STATE_FAILED(5)`.
* The SDK also triggers `onConnected` or `onDisconnected` to notify you of the state change.
* @param settings The settings of connecting.
*/
virtual int connect(const TConnectSettings& settings, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Disconnects from the Agora channel.
*
* Once your app successful disconnects from the channel, the connection state changes to
* `CONNECTION_STATE_DISCONNECTED(1)`. You are also notified with the callback
* \ref IRtcConnectionObserver::onDisconnected "onDisconnected".
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int disconnect(aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Starts the last-mile network probe test.
*
* Call this method before connecting to the channel to get the uplink and
* downlink last-mile network statistics, including the bandwidth, packet loss, jitter, and
* round-trip time (RTT).
*
* After you enable the last-mile network probe test, the SDK triggers the following callbacks:
* - \ref IRtcConnectionObserver::onLastmileQuality "onLastmileQuality": The SDK triggers this
* callback within two seconds depending on the network conditions. This callback rates the network
* conditions and is more closely linked to the user experience.
* - \ref IRtcConnectionObserver::onLastmileProbeResult "onLastmileProbeResult": The SDK triggers
* this callback within 30 seconds depending on the network conditions. This callback reports the
* real-time statistics of the network conditions and is more objective.
*
* @note
* - Do not call any other method before receiving the \ref IRtcConnectionObserver::onLastmileQuality
* "onLastmileQuality" and \ref IRtcConnectionObserver::onLastmileProbeResult "onLastmileProbeResult"
* callbacks. Otherwise, the callbacks may be interrupted.
* - In the live-broadcast profile, a host should not call this method after connecting to a channel.
*
* @param config The configurations of the last-mile network probe test. See \ref agora::rtc::LastmileProbeConfig "LastmileProbeConfig".
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int startLastmileProbeTest(const LastmileProbeConfig& config, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Stops the last-mile network probe test.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int stopLastmileProbeTest(aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Renews the token.
*
* The token expires after a certain period of time.
* When the \ref IRtcConnectionObserver::onError "onError" callback reports `ERR_TOKEN_EXPIRED(109)`, you must generate a new token from the server
* and then call this method to renew it. Otherwise, the SDK disconnects from the Agora channel.
*
* @param token The pointer to the new token.
*/
virtual int renewToken(const char* token, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Gets the connection information.
*
* @return
* - The pointer to the \ref agora::rtc::TConnectionInfo "TConnectionInfo" object: Success.
* - A null pointer: Failure.
*/
virtual TConnectionInfo getConnectionInfo() = 0;
/**
* Gets the \ref agora::rtc::ILocalUser "ILocalUser" object.
*
* @return
* - The pointer to the \ref agora::rtc::ILocalUser "ILocalUser" object: Success.
* - A null pointer: Failure.
*/
virtual ILocalUser* getLocalUser() = 0;
/**
* Gets the information of all the remote users in the channel.
*
* After a user successfully connects to the channel, you can also get the information of this remote user
* with the \ref IRtcConnectionObserver::onUserJoined "onUserJoined" callback.
*
* @param [out] users The reference to the \ref agora::UserList "UserList" object, which contains the information of all users
* in the channel.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getRemoteUsers(UserList& users) = 0;
/**
* Gets the information of a specified remote user in the channel.
*
* @param [in] userId ID of the user whose information you want to get.
* @param [out] userInfo The reference to the \ref agora::UserInfo "UserInfo" object, which contains the information of the
* specified user.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getUserInfo(user_id_t userId, agora::UserInfo& userInfo) = 0;
/**
* Registers an RTC connection observer. You can call this method only after creating an `IRtcConnection` object.
*
* @param observer The pointer to the IRtcConnectionObserver object.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int registerObserver(IRtcConnectionObserver* observer, void(*safeDeleter)(IRtcConnectionObserver*) = NULL, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Releases the registered IRtcConnectionObserver object.
*
* @param observer The pointer to the IRtcConnectionObserver object created by the \ref registerObserver
* "registerObserver" method.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int unregisterObserver(IRtcConnectionObserver* observer) = 0;
/**
* Registers an network observer object.
*
* @param observer The pointer to the INetworkObserver object.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int registerNetworkObserver(INetworkObserver* observer, void(*safeDeleter)(INetworkObserver*) = NULL, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Releases the registered INetworkObserver object.
*
* @param observer The pointer to the INetworkObserver object created by the \ref registerNetworkObserver
* "registerNetworkObserver" method.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int unregisterNetworkObserver(INetworkObserver* observer) = 0;
/**
* Gets the ID of the connection.
*
* @return
* - The connection ID: Success.
* - A null pointer: Failure.
*/
virtual conn_id_t getConnId() = 0;
/**
* Gets the transportation statistics of the RTC connection.
*
* @return
* - The pointer to \ref agora::rtc::RtcStats "RtcStats": Success.
* - A null pointer: Failure.
*/
virtual RtcStats getTransportStats() = 0;
/**
* Gets the IAgoraParameter object.
*
* @return
* - The pointer to the \ref agora::base::IAgoraParameter "IAgoraParameter" object.
* - A null pointer: Failure.
*/
virtual agora::base::IAgoraParameter* getAgoraParameter() = 0;
/**
* Creates a data stream.
*
* Each user can create up to five data streams during the lifecycle of an RTC connection.
*
* @note Set both the `reliable` and `ordered` parameters as `true` or `false`. Do not set one as `true` and the other as `false`.
*
* @param streamId The pointer to the ID of the data stream.
* @param reliable Whether to guarantee the receivers receive the data stream within five seconds:
* - `true`: Guarantee that the receivers receive the data stream within five seconds. If the receivers do not receive the data stream within five seconds, the SDK reports an error to the application.
* - `false`: Do not guarantee that the receivers receive the data stream within five seconds and the SDK does not report any error message for data stream delay or missing.
* @param ordered Whether the receivers receive the data stream in the order of sending:
* - `true`: The receivers receive the data stream in the order of sending.
* - `false`: The receivers do not receive the data stream in the order of sending.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int createDataStream(int* streamId, bool reliable, bool ordered, bool sync) = 0;
/** Sends data stream messages to all users in a channel.
*
* @note This method has the following restrictions:
* - Up to 30 packets can be sent per second in a channel with a maximum size of 1 kB for each packet.
* - Each client can send up to 6 kB of data per second.
* - Each user can have up to five data streams simultaneously.
*
* @param streamId The ID of the sent data stream, returned in the \ref agora::rtc::IRtcConnection::createDataStream "createDataStream" method.
* @param data The pointer to the sent data.
* @param length The length of the sent data.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int sendStreamMessage(int streamId, const char* data, size_t length, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/** Enables/Disables the built-in encryption.
*
* In scenarios requiring high security, Agora recommends calling this method to enable the built-in encryption before joining a channel.
*
* All users in the same channel must use the same encryption mode and encryption key. Once all users leave the channel, the encryption key of this channel is automatically cleared.
*
* @note
* - If you enable the built-in encryption, you cannot use the RTMP streaming function.
*
* @param enabled Whether to enable the built-in encryption:
* - true: Enable the built-in encryption.
* - false: Disable the built-in encryption.
* @param config Configurations of built-in encryption schemas. See \ref agora::rtc::EncryptionConfig "EncryptionConfig".
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int enableEncryption(bool enabled, const EncryptionConfig& config, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Reports a custom event to Agora.
*
* @param id The custom event ID.
* @param category The category of the custom event.
* @param event The custom event to report.
* @param label The label of the custom event.
* @param value The value of the custom event.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int sendCustomReportMessage(const char* id, const char* category, const char* event, const char* label, int value, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/** Gets the user information by user account, which is in string format.
*
* @param userAccount The user account of the user.
* @param [in,out] userInfo A \ref rtc::UserInfo "UserInfo" object that identifies the user:
* - Input: A userInfo object.
* - Output: A userInfo object that contains the user account and user ID of the user.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getUserInfoByUserAccount(const char* userAccount, rtc::UserInfo* userInfo) = 0;
/** Gets the user information by user ID, which is in integer format.
*
* @param uid The ID of the remote user.
* @param [in,out] userInfo A \ref rtc::UserInfo "UserInfo" object that identifies the user:
* - Input: A userInfo object.
* - Output: A userInfo object that contains the user account and user ID of the user.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getUserInfoByUid(uid_t uid, rtc::UserInfo* userInfo) = 0;
};
/**
* The IRtcConnectionObserver class, which observes the connection state of the SDK.
*/
class IRtcConnectionObserver {
public:
virtual ~IRtcConnectionObserver() {}
/**
* Occurs when the connection state between the SDK and the Agora channel changes to `CONNECTION_STATE_CONNECTED(3)`.
*
* @param connectionInfo The information of the connection. See \ref agora::rtc::TConnectionInfo "TConnectionInfo".
* @param reason The reason of the connection state change. See #CONNECTION_CHANGED_REASON_TYPE.
*/
virtual void onConnected(const TConnectionInfo& connectionInfo, CONNECTION_CHANGED_REASON_TYPE reason) = 0;
/**
* Occurs when the connection state between the SDK and the Agora channel changes to `CONNECTION_STATE_DISCONNECTED(1)`.
*
* @param connectionInfo The information of the connection. See \ref agora::rtc::TConnectionInfo "TConnectionInfo".
* @param reason The reason of the connection state change. See #CONNECTION_CHANGED_REASON_TYPE.
*/
virtual void onDisconnected(const TConnectionInfo& connectionInfo, CONNECTION_CHANGED_REASON_TYPE reason) = 0;
/**
* Occurs when the connection state between the SDK and the Agora channel changes to `CONNECTION_STATE_CONNECTING(2)`.
*
* @param connectionInfo The information of the connection. See \ref agora::rtc::TConnectionInfo "TConnectionInfo".
* @param reason The reason of the connection state change. See #CONNECTION_CHANGED_REASON_TYPE.
*/
virtual void onConnecting(const TConnectionInfo& connectionInfo, CONNECTION_CHANGED_REASON_TYPE reason) = 0;
/**
* Occurs when the connection state between the SDK and the Agora channel changes to `CONNECTION_STATE_RECONNECTING(4)`.
*
* @param connectionInfo The information of the connection. See \ref agora::rtc::TConnectionInfo "TConnectionInfo".
* @param reason The reason of the connection state change. See #CONNECTION_CHANGED_REASON_TYPE.
*/
virtual void onReconnecting(const TConnectionInfo& connectionInfo, CONNECTION_CHANGED_REASON_TYPE reason) = 0;
// This should be deleted. onConnected is enough.
virtual void onReconnected(const TConnectionInfo& connectionInfo, CONNECTION_CHANGED_REASON_TYPE reason) = 0;
/**
* Occurs when the SDK loses connection with the Agora channel.
*
* @param connectionInfo The information of the connection. See \ref agora::rtc::TConnectionInfo "TConnectionInfo".
*/
virtual void onConnectionLost(const TConnectionInfo& connectionInfo) = 0;
/**
* Reports the quality of the last-mile network.
*
* The SDK triggers this callback within two seconds after the app calls \ref IRtcConnection::startLastmileProbeTest "startLastmileProbeTest".
*
* @param quality Quality of the last-mile network: #QUALITY_TYPE.
*/
virtual void onLastmileQuality(const QUALITY_TYPE quality) = 0;
/**
* Reports the result of the last-mile network probe test.
*
* The SDK triggers this callback within 30 seconds after the app calls \ref IRtcConnection::startLastmileProbeTest "startLastmileProbeTest".
*
* @param result The result of the last-mile network probe test: \ref agora::rtc::LastmileProbeResult "LastmileProbeResult".
*/
virtual void onLastmileProbeResult(const LastmileProbeResult& result) = 0;
/**
* Occurs when the token expires in 30 seconds.
*
* The SDK triggers this callback to remind the app to get a new token before the token privilege expires.
*
* Upon receiving this callback, you must generate a new token on your server and call \ref IRtcConnection::renewToken
* "renewToken" to pass the new token to the SDK.
*
* @param token The pointer to the token that expires in 30 seconds.
*/
virtual void onTokenPrivilegeWillExpire(const char* token) = 0;
/**
* Occurs when the token has expired.
*
* Upon receiving this callback, you must generate a new token on your server and call \ref IRtcConnection::renewToken
* "renewToken" to pass the new token to the SDK.
*/
virtual void onTokenPrivilegeDidExpire() = 0;
/**
* Occurs when the connection state between the SDK and the Agora channel changes to `CONNECTION_STATE_FAILED(5)`.
*
* @param connectionInfo The connection information: TConnectionInfo.
* @param reason The reason of the connection state change: #CONNECTION_CHANGED_REASON_TYPE.
*/
virtual void onConnectionFailure(const TConnectionInfo& connectionInfo,
CONNECTION_CHANGED_REASON_TYPE reason) = 0;
/**
* Occurs when a remote user joins the channel.
*
* You can get the ID of the remote user in this callback.
*
* @param userId The ID of the remote user who joins the channel.
*/
virtual void onUserJoined(user_id_t userId) = 0;
/**
* Occurs when a remote user leaves the channel.
*
* You can know why the user leaves the channel through the `reason` parameter.
*
* @param userId The ID of the user who leaves the channel.
* @param reason The reason why the remote user leaves the channel: #USER_OFFLINE_REASON_TYPE.
*/
virtual void onUserLeft(user_id_t userId, USER_OFFLINE_REASON_TYPE reason) = 0;
/**
* Reports the transport statistics of the connection.
*
* The SDK triggers this callback once every two seconds when the connection state is `CONNECTION_STATE_CONNECTED`.
*
* @param stats The pointer to \ref rtc::RtcStats "RtcStats".
*/
virtual void onTransportStats(const RtcStats& stats) = 0;
/**
* Occurs when the role of the local user changes.
*
* @param oldRole The previous role of the local user: \ref rtc::CLIENT_ROLE_TYPE "CLIENT_ROLE_TYPE".
* @param newRole The current role of the local user: \ref rtc::CLIENT_ROLE_TYPE "CLIENT_ROLE_TYPE".
* @param newRoleOptions The client role options of the current role of the local user: \ref rtc::ClientRoleOptions "ClientRoleOptions".
*/
virtual void onChangeRoleSuccess(CLIENT_ROLE_TYPE oldRole, CLIENT_ROLE_TYPE newRole, const ClientRoleOptions& newRoleOptions) {
(void)oldRole;
(void)newRole;
(void)newRoleOptions;
}
/**
* Occurs when the local user fails to change the user role.
*/
virtual void onChangeRoleFailure(CLIENT_ROLE_CHANGE_FAILED_REASON reason, CLIENT_ROLE_TYPE currentRole) {
(void)reason;
(void)currentRole;
}
/**
* Occurs when connection license verification fails
*
* You can know the reason accordding to error code
* @param error verify fail reason
*/
virtual void onLicenseValidationFailure(LICENSE_ERROR_TYPE error) {
(void)error;
}
/**
* Reports the network quality of each user.
*
* The SDK triggers this callback once every two seconds to report the uplink and downlink network conditions
* of each user in the channel, including the local user.
*
* @param userId The ID of the user. If `userId` is empty, this callback reports the network quality of the local user.
* @param txQuality The uplink network quality: #QUALITY_TYPE.
* @param rxQuality The downlink network quality: #QUALITY_TYPE.
*/
virtual void onUserNetworkQuality(user_id_t userId, QUALITY_TYPE txQuality,
QUALITY_TYPE rxQuality) {
(void)userId;
(void)txQuality;
(void)rxQuality;
}
/** Occurs when the network type is changed.
* @param type The current network type. See #NETWORK_TYPE.
*/
virtual void onNetworkTypeChanged(NETWORK_TYPE type) {
(void)type;
}
/** Reports result of Content Inspect*/
virtual void onContentInspectResult(media::CONTENT_INSPECT_RESULT result) { (void)result; }
/** Occurs when takeSnapshot API result is obtained
*
*
* @brief snapshot taken callback
*
* @param channel channel name
* @param uid user id
* @param filePath image is saveed file path
* @param width image width
* @param height image height
* @param errCode 0 is ok negative is error
*/
virtual void onSnapshotTaken(user_id_t userId, const char* filePath, int width, int height, int errCode) {
(void)userId;
(void)filePath;
(void)width;
(void)height;
(void)errCode;
}
/**
* Reports the error code and error message.
* @param error The error code: #ERROR_CODE_TYPE.
* @param msg The error message.
*/
virtual void onError(ERROR_CODE_TYPE error, const char* msg) {
(void)error;
(void)msg;
}
/**
* Occurs when the state of the channel media relay changes.
*
*
* @param state The state code:
* - `RELAY_STATE_IDLE(0)`: The SDK is initializing.
* - `RELAY_STATE_CONNECTING(1)`: The SDK tries to relay the media stream to the destination
* channel.
* - `RELAY_STATE_RUNNING(2)`: The SDK successfully relays the media stream to the destination
* channel.
* - `RELAY_STATE_FAILURE(3)`: A failure occurs. See the details in `code`.
* @param code The error code:
* - `RELAY_OK(0)`: The state is normal.
* - `RELAY_ERROR_SERVER_ERROR_RESPONSE(1)`: An error occurs in the server response.
* - `RELAY_ERROR_SERVER_NO_RESPONSE(2)`: No server response. You can call the leaveChannel method
* to leave the channel.
* - `RELAY_ERROR_NO_RESOURCE_AVAILABLE(3)`: The SDK fails to access the service, probably due to
* limited resources of the server.
* - `RELAY_ERROR_FAILED_JOIN_SRC(4)`: Fails to send the relay request.
* - `RELAY_ERROR_FAILED_JOIN_DEST(5)`: Fails to accept the relay request.
* - `RELAY_ERROR_FAILED_PACKET_RECEIVED_FROM_SRC(6)`: The server fails to receive the media
* stream.
* - `RELAY_ERROR_FAILED_PACKET_SENT_TO_DEST(7)`: The server fails to send the media stream.
* - `RELAY_ERROR_SERVER_CONNECTION_LOST(8)`: The SDK disconnects from the server due to poor
* network connections. You can call the leaveChannel method to leave the channel.
* - `RELAY_ERROR_INTERNAL_ERROR(9)`: An internal error occurs in the server.
* - `RELAY_ERROR_SRC_TOKEN_EXPIRED(10)`: The token of the source channel has expired.
* - `RELAY_ERROR_DEST_TOKEN_EXPIRED(11)`: The token of the destination channel has expired.
*/
virtual void onChannelMediaRelayStateChanged(int state, int code) = 0;
/** Occurs when the local user successfully registers a user account by calling the \ref IRtcEngine::joinChannelWithUserAccount "joinChannelWithUserAccount" method.This callback reports the user ID and user account of the local user.
*
* @param uid The ID of the local user.
* @param userAccount The user account of the local user.
*/
virtual void onLocalUserRegistered(uid_t uid, const char* userAccount) {
(void)uid;
(void)userAccount;
}
/** Technical Preview, please do not depend on this event. */
virtual void onUserAccountUpdated(uid_t uid, const char* userAccount) {
(void)uid;
(void)userAccount;
}
/**
* Reports the error that occurs when receiving data stream messages.
*
* @param userId The ID of the user sending the data stream.
* @param streamId the ID of the sent data stream, returned in the \ref agora::rtc::IRtcConnection::createDataStream "createDataStream" method.
* @param code The error code.
* @param missed The number of lost messages.
* @param cached The number of incoming cached messages when the data stream is interrupted.
*/
virtual void onStreamMessageError(user_id_t userId, int streamId, int code, int missed,
int cached) {
(void)userId;
(void)streamId;
(void)code;
(void)missed;
(void)cached;
}
/**
* Reports the error type of encryption.
* @param type See #ENCRYPTION_ERROR_TYPE.
*/
virtual void onEncryptionError(ENCRYPTION_ERROR_TYPE errorType) {
(void)errorType;
}
/**
* Reports the user log upload result
* @param requestId RequestId of the upload
* @param success Is upload success
* @param reason Reason of the upload, 0: OK, 1 Network Error, 2 Server Error.
*/
virtual void onUploadLogResult(const char* requestId, bool success, UPLOAD_ERROR_REASON reason) {
(void)requestId;
(void)success;
(void)reason;
}
/**
* Occurs when receive use rtm response.
*
* @param code The error code:
*/
virtual void onSetRtmFlagResult(int code) {
(void)code;
}
/** Occurs when the WIFI message need be sent to the user.
*
* @param reason The reason of notifying the user of a message.
* @param action Suggest an action for the user.
* @param wlAccMsg The message content of notifying the user.
*/
virtual void onWlAccMessage(WLACC_MESSAGE_REASON reason, WLACC_SUGGEST_ACTION action, const char* wlAccMsg) {
(void)reason;
(void)action;
(void)wlAccMsg;
}
/** Occurs when SDK statistics wifi acceleration optimization effect.
*
* @param currentStats Instantaneous value of optimization effect.
* @param averageStats Average value of cumulative optimization effect.
*/
virtual void onWlAccStats(const WlAccStats& currentStats, const WlAccStats& averageStats) {
(void)currentStats;
(void)averageStats;
}
};
class INetworkObserver {
public:
virtual ~INetworkObserver() {}
public:
/**
* Occurs when downlink network info is updated.
*
* This callback is used for notifying user to adjust the send pace based
* on the target bitrate.
*
* @param info The uplink network info collections.
*/
virtual void onUplinkNetworkInfoUpdated(const UplinkNetworkInfo& info) {
(void)info;
}
/**
* Occurs when downlink network info is updated.
*
* This callback is used for notifying user to switch major/minor stream if needed.
*
* @param info The downlink network info collections.
*/
virtual void onDownlinkNetworkInfoUpdated(const DownlinkNetworkInfo& info) {
(void)info;
}
};
} // namespace rtc
} // namespace agora

View File

@@ -0,0 +1,392 @@
//
// Agora RTMP connection
//
// Created by Haonong Yu in 2020-02.
// Copyright (c) 2020 Agora.io. All rights reserved.
//
#pragma once // NOLINT(build/header_guard)
#include "AgoraBase.h"
#include "AgoraRefPtr.h"
#include <aosl/api/cpp/aosl_ares_class.h>
namespace agora {
namespace rtc {
class IRtmpLocalUser;
/**
* Configurations for the RTMP audio stream.
*/
struct RtmpStreamingAudioConfiguration {
/**
* Sampling rate (Hz). The default value is 44100 (i.e. 44.1kHz).
*/
int sampleRateHz;
/**
* Number of bytes per sample. The default value is 2 (i.e. 16-bit PCM).
*/
int bytesPerSample;
/**
* Number of channels. The default value is 1 (i.e. mono).
*/
int numberOfChannels;
/**
* The target bitrate (Kbps) of the output audio stream to be published.
* The default value is 48 Kbps.
*/
int bitrate;
RtmpStreamingAudioConfiguration(): sampleRateHz(44100), bytesPerSample(2),
numberOfChannels(1), bitrate(48000) {}
};
/**
* Configurations for the RTMP video stream.
*/
struct RtmpStreamingVideoConfiguration {
/**
* The width (in pixels) of the video. The default value is 640.
*
* @note
* - The value of the dimension (with the |height| below) does not indicate the orientation mode
* of the output ratio. For how to set the video orientation,
* see {@link OrientationMode OrientationMode}.
*/
int width;
/**
* The height (in pixels) of the video. The default value is 360.
*
* @note
* - The value of the dimension (with the |width| above) does not indicate the orientation mode
* of the output ratio. For how to set the video orientation,
* see {@link OrientationMode OrientationMode}.
*/
int height;
/**
* Frame rate (fps) of the output video stream to be published. The default
* value is 15 fps.
*/
int framerate;
/**
* The target bitrate (Kbps) of the output video stream to be published.
* The default value is 800 Kbps.
*/
int bitrate;
/**
* (For future use) The maximum bitrate (Kbps) for video.
* The default value is 960 Kbps.
*/
int maxBitrate;
/**
* (For future use) The minimum bitrate (Kbps) for video.
* The default value is 600 Kbps.
*/
int minBitrate;
/**
* The interval between two keyframes.
* The default value is 2000ms.
*/
unsigned int gopInMs;
/**
* Whether the encoder enables hard coding or soft coding.
* The default value is 0.
* 0: default
* 1: hardware encoder
* 2: software encoder
*/
int encoderHwSwMode;
/**
* Whether the encoder enables CBR coding or VBR coding.
* The default value is 0.
* 0: CBR
* 1: VBR
*/
int encoderBitrateControlMode;
/**
* The orientation mode.
* See {@link ORIENTATION_MODE ORIENTATION_MODE}.
*/
ORIENTATION_MODE orientationMode;
RtmpStreamingVideoConfiguration(): width(640), height(360), framerate(15),
bitrate(800), maxBitrate(960), minBitrate(600), gopInMs(2000), encoderHwSwMode(0),encoderBitrateControlMode(0),
orientationMode(ORIENTATION_MODE_ADAPTIVE) {}
};
/**
* The RTMP Connection error codes.
*/
enum RTMP_CONNECTION_ERROR {
/**
* 0: No error occurs.
*/
RTMP_CONNECTION_ERR_OK = 0,
/**
* 1: A general error occurs (no specified reason).
*/
RTMP_CONNECTION_ERR_FAILED = 1,
/**
* 2: The rtmp url is invalid.
*/
RTMP_CONNECTION_ERR_INVALID_URL = 2,
/**
* 3: Already exist stream name.
*/
RTMP_CONNECTION_ERR_BAD_NAME = 3,
};
/**
* The connection state between the SDK and the RTMP server.
*/
enum RTMP_CONNECTION_STATE {
/**
* 1: The SDK is disconnected from the RTMP server.
*
* This is the initial state when an RTMP Connetion is created by
* the \ref IAgoraService::createRtmoConnection "createRtmpConnection" method.
*
* The RTMP Connection also enters this state if you call the
* \ref disconnect "disconnect" method when the SDK is in the
* STATE_CONNECTING(2), STATE_CONNECTED(3), STATE_RECONNECTING(4) or
* STATE_FAILED(5) state.
*/
STATE_DISCONNECTED = 1,
/**
* 2: The SDK is connecting to the RTMP server.
*
* The SDK goes to this state after you call the \ref connect "connect" method,
* indicating that the SDK is in the process of establishing a connection
* to the RTMP server.
*
* Once successfully connected, it enters the STATE_CONNECTED(3) state.
*
* If the SDK fails to connect to RTMP server, the SDK goes to STATE_FAILED(5).
*/
STATE_CONNECTING = 2,
/**
* 3: The SDK is connected to the RTMP server.
*
* This state indicates that the SDK has established a connection to the
* RTMP server, and you can publish media streams through this connection.
*
* Once the connection is interrupted, for example, due to network deterioration or
* network type change, the SDK tries to reconnect to the RTMP server
* and enters the STATE_RECONNECTING(4) state.
*/
STATE_CONNECTED = 3,
/**
* 4: The SDK is reconnecting to the RTMP server.
*
* This state indicates that the connection is interrupted by
* some network issue. The SDK keeps trying connecting to the
* server. If the SDK fails to reconnect, the SDK goes to
* STATE_FAILED(5).
*/
STATE_RECONNECTING = 4,
/**
* 5: The SDK fails to connect to the RTMP server.
*
* In this state, SDK stops connecting to the server. Call the
* - \ref IRtmpConnection::disconnect "disconnect" method to leave this state and the
* - \ref IRtmpConnection::connect "connect" method to reconnect.
*/
STATE_FAILED = 5,
/**
* 6: The SDK is reconnected to the RTMP server.
*
* This state indicates that the connection is interrupted by
* some network issue. The SDK keeps trying connecting to the
* server. If the SDK reconnected to server, the SDK goes to
* STATE_RECONNECTED(6).
*/
STATE_RECONNECTED = 6
};
/**
* Configurations for the RTMP connection.
*/
struct RtmpConnectionConfiguration {
RtmpStreamingAudioConfiguration audioConfig;
RtmpStreamingVideoConfiguration videoConfig;
bool audioOnly;
RtmpConnectionConfiguration() : audioOnly(false) {}
};
/**
* The information on the RTMP Connection.
*/
struct RtmpConnectionInfo {
/**
* The state of the current connection: #RTMP_CONNECTION_STATE.
*/
RTMP_CONNECTION_STATE state;
RtmpConnectionInfo() : state(STATE_DISCONNECTED) {}
};
/**
* The IRtmpConnectionObserver class, which observes the RTMP connection state of the SDK.
*/
class IRtmpConnectionObserver {
public:
/**
* Occurs when the connection state between the SDK and the RTMP server changes to STATE_CONNECTED(3).
*
* @param connectionInfo The information of the current connection: RtmpConnectionInfo.
*/
virtual void onConnected(const RtmpConnectionInfo& connectionInfo) = 0;
/**
* Occurs when the connection state between the SDK and the RTMP server changes to STATE_DISCONNECTED(1).
*
* @param connectionInfo The information of the current connection: RtmpConnectionInfo.
*/
virtual void onDisconnected(const RtmpConnectionInfo& connectionInfo) = 0;
/**
* Occurs when the connection state between the SDK and RTMP server changes to STATE_RECONNECTING(4).
*
* @param connectionInfo The information of the current connection: RtmpConnectionInfo.
*/
virtual void onReconnecting(const RtmpConnectionInfo& connectionInfo) = 0;
/**
* Occurs when the connection state between the SDK and RTMP server changes to STATE_RECONNECTED(6).
*
* @param connectionInfo The information of the current connection: RtmpConnectionInfo.
*/
virtual void onReconnected(const RtmpConnectionInfo& connectionInfo) = 0;
/**
* Occurs when the connection state between the SDK and the RTMP server changes to STATE_FAILED(5).
*
* @param connectionInfo The connection information: RtmpConnectionInfo.
* @param errCode The error code for the connection failure.
*/
virtual void onConnectionFailure(const RtmpConnectionInfo& connectionInfo,
RTMP_CONNECTION_ERROR errCode) = 0;
/**
* Occurs every 1s when the connection transmits data, report the current video bitrate, audio bitrate and video framerate.
*
* @param video_width The width of the video frame actually pushed out
* @param video_height The height of the video frame actually pushed out
* @param video_bitrate The actual bitrate of the video stream being pushed out
* @param audio_bitrate The actual bitrate of the audio stream being pushed out
* @param video_frame_rate The frame rate of the video stream actually pushed out
*/
virtual void onTransferStatistics(uint64_t video_width, uint64_t video_height, uint64_t video_bitrate, uint64_t audio_bitrate, uint64_t video_frame_rate, uint64_t push_video_frame_cnt, uint64_t pop_video_frame_cnt) = 0;
virtual ~IRtmpConnectionObserver() {}
};
/**
* The IRtmpConnection class.
*
* With this class, an app can establish a connection to a RTMP server.
* Once connected, the app gets an RtmpUser object, which
* can publish media streams to the RTMP server.
*
* Connecting to the server is done asynchronous, and apps can listen for the
* connection states or events with IRtmpConnectionObserver.
*/
class IRtmpConnection : public RefCountInterface {
public:
~IRtmpConnection() {}
/**
* Connects to a RTMP server.
*
* When the method call succeeds, the RTMP connection state changes to
* STATE_CONNECTING(2).
*
* Depending on the success or failure of the connection establishment, the RTMP
* connection will make a second state transition to either
* STATE_CONNECTED(3) or STATE_FAILED(5). You will also be notified with the either
* onConnected() or onDisconnected().
*
* @param url The CDN streaming URL in the RTMP format. The maximum length of this parameter is 1024
* bytes. The URL address must not contain special characters, such as Chinese language characters.
* @return
* - 0: Success.
* - < 0: Failure.
* - ERR_INVALID_ARGUMENT: The passed in argument is invalid.
* - ERR_INVALID_STATE: The current connection state is not STATE_DISCONNECTED(3).
*/
virtual int connect(const char* url, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Disconnects from the RTMP server.
*
* A successful call of this method changes the connection state to
* STATE_DISCONNECTED(4). You will be notified with the callback
* \ref onDisconnected "onDisconnected".
*/
virtual int disconnect(aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Gets the current connection information.
*
* @return
* - A pointer to the RtmpConnectionInfo object, if the method call succeeds.
* - An empty pointer NULL, if the method call fails.
*/
virtual RtmpConnectionInfo getConnectionInfo() = 0;
/**
* Gets the IRtmpUser object.
*
* @return
* - A pointer to the IRtmpUser object, if the method call succeeds.
* - An empty pointer NULL, if the method call fails.
*/
virtual IRtmpLocalUser* getRtmpLocalUser() = 0;
/**
* Registers an IRtmpConnectionObserver object.
*
* @param observer A pointer to the IRtmpConnectionObserver object.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int registerObserver(IRtmpConnectionObserver* observer, void(*safeDeleter)(IRtmpConnectionObserver*) = NULL, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Releases the registered IRtmpConnectionObserver object.
*
* @param observer The pointer to the IRtmpConnectionObserver object created by the \ref registerObserver
* "registerObserver" method.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int unregisterObserver(IRtmpConnectionObserver* observer) = 0;
};
} // namespace rtc
} // namespace agora

View File

@@ -0,0 +1,299 @@
//
// Agora RTMP connection
//
// Created by Haonong Yu in 2020-02.
// Copyright (c) 2020 Agora.io. All rights reserved.
//
#pragma once // NOLINT(build/header_guard)
#include "NGIAgoraAudioTrack.h"
#include "NGIAgoraVideoTrack.h"
namespace agora {
namespace rtc {
struct RtmpStreamingAudioConfiguration;
struct RtmpStreamingVideoConfiguration;
/**
* The error occurs while publising audio stream.
*/
enum PublishAudioError {
/**
* 0: No error occurs.
*/
PUBLISH_AUDIO_ERR_OK = 0,
/**
* 1: A general error occurs (no specified reason).
*/
PUBLISH_AUDIO_ERR_FAILED = 1,
};
/**
* The error occurs while publising video stream.
*/
enum PublishVideoError {
/**
* 0: No error occurs.
*/
PUBLISH_VIDEO_ERR_OK = 0,
/**
* 1: A general error occurs (no specified reason).
*/
PUBLISH_VIDEO_ERR_FAILED = 1,
};
/**
* The IRtmpLocalUserObserver class.
*/
class IRtmpLocalUserObserver {
public:
virtual ~IRtmpLocalUserObserver() {}
/**
* Occurs when the first packet of the local audio track is sent, indicating that the local audio track
* is successfully published.
*
* @param audioTrack The pointer to ILocalAudioTrack.
*/
virtual void onAudioTrackPublishSuccess(agora_refptr<rtc::ILocalAudioTrack> audioTrack) = 0;
/**
* @deprecated This method will not be called back
*/
virtual void onAudioTrackPublishStart(agora_refptr<rtc::ILocalAudioTrack> audioTrack) = 0;
/**
* @deprecated This method will not be called back
*/
virtual void onAudioTrackUnpublished(agora_refptr<rtc::ILocalAudioTrack> audioTrack) = 0;
/**
* Occurs when the local audio track fails to be published.
*
* @param audioTrack The pointer to ILocalAudioTrack.
* @param error The error information: #RtmpAudioStreamError.
*/
virtual void onAudioTrackPublicationFailure(agora_refptr<rtc::ILocalAudioTrack> audioTrack,
PublishAudioError error) = 0;
/**
* Occurs when the first packet of the local video track is sent, indicating that the local video track
* is successfully published.
* @param videoTrack The pointer to ILocalVideoTrack.
*/
virtual void onVideoTrackPublishSuccess(agora_refptr<rtc::ILocalVideoTrack> videoTrack) = 0;
/**
* @deprecated This method will not be called back
*/
virtual void onVideoTrackPublishStart(agora_refptr<rtc::ILocalVideoTrack> videoTrack) = 0;
/**
* @deprecated This method will not be called back
*/
virtual void onVideoTrackUnpublished(agora_refptr<rtc::ILocalVideoTrack> videoTrack) = 0;
/**
* Occurs when the local video track fails to be published.
*
* @param videoTrack The pointer to ILocalVideoTrack.
* @param error The error information: #RtmpVideoStreamError.
*/
virtual void onVideoTrackPublicationFailure(agora_refptr<rtc::ILocalVideoTrack> videoTrack,
PublishVideoError error) = 0;
};
/**
* The IRtmpLocalUser class defines the behavior and state of the RTMP user.
*
* Once connected, a RTMP connection has its own user. Apps can get the
* user object using \ref agora::rtmp::IRtmpConnection::getUser
* "IRtmpConnection::getUser".
*/
class IRtmpLocalUser {
public:
enum VideoBitrateAdjustType {
None = 0,
Increasing = 1, // The buffer is in good declining state to increase bitrate
Decreasing = 2, // The buffer is in bad increasing state to decrease bitrate
};
virtual ~IRtmpLocalUser() {}
/**
* Set the parameters of the audio encoder when pushing the stream
*
* @param config Audio encoder parameters
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setAudioStreamConfiguration(const RtmpStreamingAudioConfiguration& config, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Set the parameters of the video encoder when pushing the stream
*
* @param config Video encoder parameters
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setVideoStreamConfiguration(const RtmpStreamingVideoConfiguration& config, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Adjusts the audio volume for publishing.
*
* @param volume The volume for publishing. The value ranges between 0 and 100 (default).
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int adjustRecordingSignalVolume(int volume, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Gets the current volume for publishing.
* @param volume A pointer to the publishing volume.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int getRecordingSignalVolume(int32_t* volume) = 0;
/**
* Dynamically adjust the bit rate parameters of the video encoder in the push stream
*
* @note: When increasing the bit rate, each call increases by 50kbps;
* When you lower the bit rate, you reduce it by 100kbps per call
*
* @param type The type of adjustment mode for the bit-rate parameter of the video encoder in the push stream:
* - `Increasing`: Increase the video encoding bitrate.
* - `Decreasing`: Reduce video encoding bitrate
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int adjustVideoBitrate(VideoBitrateAdjustType type, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Set whether to enable local video
*
* @param enabled Whether to enable local video:
* - `true`: Enable local video.
* - `false`: Disable local video.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setVideoEnabled(bool enabled, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Publishes a local audio track to the RTMP connection.
*
* @param audioTrack The local audio track to be published: ILocalAudioTrack.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int publishAudio(agora_refptr<rtc::ILocalAudioTrack> audioTrack, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Stops publishing the local audio track to the RTMP connection.
*
* @param audioTrack The local audio track that you want to stop publishing: ILocalAudioTrack.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int unpublishAudio(agora_refptr<rtc::ILocalAudioTrack> audioTrack, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Publishes a local video track to the RTMP connection.
*
* @param videoTrack The local video track to be published: ILocalVideoTrack.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int publishVideo(agora_refptr<rtc::ILocalVideoTrack> videoTrack, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Stops publishing the local video track to the RTMP connection.
*
* @param videoTrack The local video track that you want to stop publishing: ILocalVideoTrack.
* - 0: Success.
* - < 0: Failure.
*/
virtual int unpublishVideo(agora_refptr<rtc::ILocalVideoTrack> videoTrack, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Registers a RTMP user observer object.
*
* You need to implement the IRtmpLocalUserObserver class in this method. Once registered, the
* IRtmpLocalUserObserver receives events sent by the IRtmpLocalUser object.
*
* @param observer The pointer to the IRtmpLocalUserObserver object.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int registerRtmpUserObserver(IRtmpLocalUserObserver* observer, void(*safeDeleter)(IRtmpLocalUserObserver*) = NULL, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Releases the IRtmpLocalUserObserver object previously registered using registerRtmpUserObserver().
*
* @param observer The pointer to the IRtmpLocalUserObserver object that you want to release.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int unregisterRtmpUserObserver(IRtmpLocalUserObserver* observer) = 0;
/**
* Registers an audio frame observer object.
*
* @param observer A pointer to the audio frame observer object: IAudioFrameObserver.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int registerAudioFrameObserver(media::IAudioPcmFrameSink* observer, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Unregisters an audio frame observer object.
*
* @param observer A pointer to the audio frame observer object: IAudioFrameObserver.
*/
virtual void unregisterAudioFrameObserver(media::IAudioPcmFrameSink* observer) = 0;
/**
* Registers a video frame observer object.
*
* @param observer A pointer to the video frame observer: IVideoFrameObserver.
*
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int registerVideoFrameObserver(media::base::IVideoFrameObserver* observer, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Unregisters a video frame observer object.
*
* @param observer A pointer to the video frame observer: IVideoFrameObserver.
*/
virtual void unregisterVideoFrameObserver(media::base::IVideoFrameObserver* observer) = 0;
};
} // namespace rtc
} // namespace agora

View File

@@ -0,0 +1,223 @@
//
// Agora SDK
//
// Copyright (c) 2019 Agora.io. All rights reserved.
//
#pragma once // NOLINT(build/header_guard)
#include "AgoraBase.h"
#include "AgoraRefPtr.h"
#include <aosl/api/cpp/aosl_ares_class.h>
namespace agora {
namespace rtc {
/**
* The IScreenCapturer class, which provides access to the screen capturer.
*/
class IScreenCapturer : public RefCountInterface {
public:
#if defined (_WIN32) || (defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONE)
/**
* Initializes the screen capturer by specifying a display ID.
*
* @note
* This method applies to macOS only.
*
* This method shares a whole or part of a screen specified by the display ID.
* @param displayId The display ID of the screen to be shared. This parameter specifies which screen you want
* to share.
* @param regionRect The reference to the relative location of the region to the screen: Rectangle.
* - If the specified region overruns the screen, only the region within the screen will be captured.
* - If you set `width` or `height` as 0, the whole screen will be captured.
* Note that the coordinates of rectangle are relative to the window and follows system specifications.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int initWithDisplayId(int64_t displayId, const Rectangle& regionRect) = 0;
#endif
#if defined(_WIN32) || (defined(__linux__) && !defined(__ANDROID__))
/**
* Initializes the screen capturer by specifying a screen Rect.
*
* @note
* This method applies to Windows only.
*
* This method shares a whole or part of a screen specified by the screen Rect.
* @param screenRect The reference to the Rect of the screen to be shared. This parameter specifies which screen you want
* to share.
* @param regionRect The reference to the relative location of the region to the screen. See \ref agora::rtc::Rectangle &regionRect "regionRect".
* - If the specified region overruns the screen, only the region within the screen will be captured.
* - If you set `width` or `height` as 0, the whole screen will be captured.
* Note that the coordinates of rectangle are relative to the window and follows system specifications.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int initWithScreenRect(const Rectangle& screenRect,
const Rectangle& regionRect) = 0;
#endif // TARGET_OS_MAC && !TARGET_OS_IPHONE
/**
* Initializes the screen capturer by specifying a window ID.
*
* This method shares a whole or part of a window specified by the window ID.
*
* @note
* This method applies to Windows and macOS only.
* @param windowId The ID of the window to be shared. This parameter specifies which window you want
* to share.
* @param regionRect The reference to the relative location of the region to the window. See \ref agora::rtc::Rectangle &regionRect "regionRect".
* - If the specified region overruns the window, only the region within the screen will be captured.
* - If you set `width` or `height` as 0, the whole window will be captured.
* Note that the coordinates of rectangle are relative to the window and follows system specifications.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int initWithWindowId(view_t windowId, const Rectangle& regionRect) = 0;
/**
* Sets the content hint for screen sharing.
*
* A content hint suggests the type of the content being shared, so that the SDK applies different
* optimization algorithms to different types of content.
* @param contentHint The content hint for screen capture: \ref rtc::VIDEO_CONTENT_HINT "VIDEO_CONTENT_HINT".
* @return
* - 0: Success.
* - < 0: Failure.
* - ERR_NOT_READY: No screen or window is being shared.
*/
virtual int setContentHint(VIDEO_CONTENT_HINT contentHint, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Updates the screen capture region.
* @param regionRect The reference to the relative location of the region to the screen or window. See \ref agora::rtc::Rectangle "Rectangle".
* - If the specified region overruns the screen or window, the screen capturer captures only the region within it.
* - If you set `width` or `height` as 0, the SDK shares the whole screen or window.
* @return
* - 0: Success.
* - < 0: Failure.
* - No screen or window is being shared.
*/
virtual int updateScreenCaptureRegion(const Rectangle& regionRect, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Set orientation of the captured screen image
* @param VIDEO_ORIENTATION orientaion of the device 0(by default), 90, 180, 270
*/
virtual int setScreenOrientation(VIDEO_ORIENTATION orientation, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Set frame rate of the screen capture source
* @param rate frame rate (in fps)
*/
virtual int setFrameRate(int rate, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
#if defined(__ANDROID__)
/**
* Initializes the screen capturer by specifying the Intent data obtained from MediaProjection.
*
* This method shares the whole screen.
*
* @note
* This method applies to Android only.
* @param data The Intent data from `onActivityResult (int requestCode, int resultCode, Intent data)` after you create
* an Intent from `MediaProjection` and sends the Intent to `startActivityForResult`.
* @param dimensions The reference to the captured screen's resolution in terms of width &times; height.
* - If you set `width` or `height` as 0, the dimensions will be the screen's width &times; height.
* @return
* - 0: Success.
* - < 0: Failure.
* - ERR_INVALID_ARGUMENT if data is null.
*/
virtual int initWithMediaProjectionPermissionResultData(void* data,
const VideoDimensions& dimensions) = 0;
#endif // __ANDROID__
protected:
~IScreenCapturer() {}
};
#if defined(__ANDROID__) || (defined(__APPLE__) && TARGET_OS_IPHONE)
class IScreenCapturer2 : public RefCountInterface {
public:
/**
* Screen capture's resolution.
*
* @param dimensions The reference to the captured screen's resolution in terms of width &times; height.
* - If you set `width` or `height` as 0, the dimensions will be the screen's width &times; height.
* @return
* - 0: Success.
* - < 0: Failure.
* - ERR_INVALID_ARGUMENT if data is null.
*/
virtual int setScreenCaptureDimensions(const VideoDimensions& dimensions, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Updates the screen capture region.
* @param regionRect The reference to the relative location of the region to the screen or window. See \ref agora::rtc::Rectangle "Rectangle".
* - If the specified region overruns the screen or window, the screen capturer captures only the region within it.
* - If you set `width` or `height` as 0, the SDK shares the whole screen or window.
* @return
* - 0: Success.
* - < 0: Failure.
* - No screen or window is being shared.
*/
virtual int updateScreenCaptureRegion(const Rectangle& regionRect, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Set frame rate of the screen capture source
* @param rate frame rate (in fps)
*/
virtual int setFrameRate(int rate, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Set channels and sample rate of screen audio capturing
* @param channels: channels of system audio capture
* @param sampleRate: sample rate of system audio capture
* @return
* - 0: Sucess.
* - < 0: Failure
*/
virtual int setAudioRecordConfig(int channels, int sampleRate, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Set volume of screen audio capturing
* @param volume: volume of system audio capture
* @return
* - 0: Sucess.
* - < 0: Failure
*/
virtual int setAudioVolume(uint32_t volume, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
#if defined(__ANDROID__)
/**
* Sets screen sharing using the Android native class MediaProjection.
*
* When screen capture stopped, the SDK will automatically release the MediaProjection internally.
*
* @param mediaProjection MediaProjection is an Android class that provides access to screen capture and recording capabiliies.
*
* @note
* Additional MediaProjection is primarily used for specific scenarios,
* such as IOT custom devices or subprocess screen sharing.
*
* @return
* - 0: Success.
* - < 0: Failure.
* @technical preview
*/
virtual int setExternalMediaProjection(void* mediaProjection) = 0;
#endif
protected:
virtual ~IScreenCapturer2() {}
};
#endif
} // namespace rtc
} // namespace agora

View File

@@ -0,0 +1,149 @@
// Copyright (c) 2020 Agora.io. All rights reserved
// This program is confidential and proprietary to Agora.io.
// And may not be copied, reproduced, modified, disclosed to others, published
// or used, in whole or in part, without the express prior written permission
// of Agora.io.
#pragma once // NOLINT(build/header_guard)
#include "AgoraRefPtr.h"
#include "AgoraBase.h"
#include <functional>
#include <aosl/api/aosl_ref.h>
namespace agora {
namespace base {
enum SyncClientError {
kOk = 0,
kFail = -1,
kConnectSyncFailed = -2,
kConnectDatabaseFailed = -3,
kDisconnectDatabaseFailed = -4,
kDatabaseNotConnected = -5,
kCreateCollectionFailed = -6,
kCollectionNotCreated = -7,
kCollectionExisted = -8,
kInvalidParams = -9,
kNotLoggedIn = -10,
kQueryDocFailed = -11,
kDocNotCreated = -12,
};
typedef void(*syncClientCallback)(SyncClientError, void*);
typedef void(*dataBaseOpCallback)(SyncClientError, const char*, void*);
typedef void(*collectionOpCallback)(SyncClientError, const char*, const char*, void*);
typedef void(*queryDocCallback)(SyncClientError error, const char* resultJson, size_t count, bool more, void* userData);
enum SyncEventType {
kInserted = 0,
kPut = 1,
kDeleted = 2,
kToBeInserted = 3,
kToBePut = 4,
kToBeDeleted = 5,
kTransactionBegin = 6,
kTransactionEnd = 7,
kDocSyncEnd = 8,
kInitialized = 9
};
enum OP_Privilege {
OP_READ,
OP_WRITE
};
/**
* sync client observer
*/
class ISyncClientObserver {
public:
struct CollectionEvent {
SyncEventType type;
const char* path;
const char* value;
};
virtual void onCollectionEvent(const char* previousJson, const char* curJson, const char* collection, const char* docName,
const CollectionEvent* events, int eventSize) = 0;
virtual void onDatabaseEvent(const char* databaseName, SyncClientError error) = 0;
virtual void onDataException(const char* databaseName, const char* collectionName) = 0;
virtual ~ISyncClientObserver() {};
};
/**
* sync configuration
*/
struct SyncConfig {
const char* appId;
/* shakehand interval in seconds, 0 means enable manual shake hand */
uint32_t shakehand_interval;
/* connection timeout in seconds */
uint32_t connection_timeout;
/* compact interval in seconds */
uint32_t compact_interval;
SyncConfig() : appId(NULL), shakehand_interval(1), connection_timeout(10), compact_interval(3600 * 1000) {}
};
class ISyncClient : public RefCountInterface {
protected:
virtual ~ISyncClient() {}
public:
virtual int32_t registerSyncClientObserver(ISyncClientObserver* observer, void(*safeDeleter)(ISyncClientObserver*) = OPTIONAL_NULLPTR, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
virtual int32_t unregisterSyncClientObserver(ISyncClientObserver* observer) = 0;
// client operations
virtual int32_t login(const char* token, const char* channelName, user_id_t userId, syncClientCallback callback, void* userData, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
virtual int32_t queryDoc(const char* database, const char* coll, const char* range_start, const char* range_end, int64_t limits, bool doc_only, bool count_only, queryDocCallback callback, void* userData, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
virtual int32_t logout(aosl_ref_t ares = AOSL_REF_INVALID) = 0;
virtual int32_t renewToken(const char* token, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
// database operations
virtual int32_t connectDatabase(const char* database, dataBaseOpCallback callback, void* userData, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
virtual int32_t disconnectDatabase(const char* database,
dataBaseOpCallback callback, void* userData, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
virtual int32_t createCollection(const char* database, const char* collection,
const char** readable, int readSize,
collectionOpCallback callback, void* userData, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
virtual int32_t deleteCollection(const char* database, const char* collection,
collectionOpCallback callback, void* userData, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
// collection operations
virtual int32_t subscribe(const char* database, const char* collection,
util::AString& snapshotJson) = 0;
virtual int32_t unsubscribe(const char* database, const char* collection, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
virtual int32_t addReadable(const char* database, const char* coll, const char* readable, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
virtual int32_t removeReadable(const char* database, const char* coll, const char* readable, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
virtual int32_t putDoc(const char* database, const char* collection,
const char* docName, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
virtual int32_t deleteDoc(const char* database, const char* collection,
const char* docName, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
virtual int32_t getDocs(const char* database, const char* collection,
util::AString* docNames, uint32_t docSize) = 0;
// document operations
virtual int32_t putDocValue(const char* database, const char* collection,
const char* docName, const char* jsonValue, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
virtual int32_t updateDocValue(const char* database, const char* collection,
const char* docName, const char* path,
const char* jsonValue, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
virtual int32_t deleteDocValue(const char* database, const char* collection,
const char* docName, const char* path, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
virtual int32_t deleteDocValues(const char* database, const char* collection, const char* docName,
const char** path, uint32_t pathSize,
aosl_ref_t ares = AOSL_REF_INVALID) = 0;
virtual int32_t getDocValue(const char* database, const char* collection,
const char* docName, util::AString& jsonValue) = 0;
virtual int32_t hasPath(const char* database, const char* collection,
const char* docName, const char* path, bool& result) = 0;
virtual int32_t keepAliveDoc(const char* database, const char* collection,
const char* docName, uint32_t ttl, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
virtual bool isOpPermission(const char* database, const char* collection,
const char* docName, OP_Privilege op) = 0;
// sync operations
virtual int32_t shakehand(aosl_ref_t ares = AOSL_REF_INVALID) = 0;
};
}// namespace base
}// namespace agora

View File

@@ -0,0 +1,190 @@
// Copyright (c) 2020 Agora.io. All rights reserved
// This program is confidential and proprietary to Agora.io.
// And may not be copied, reproduced, modified, disclosed to others, published
// or used, in whole or in part, without the express prior written permission
// of Agora.io.
#pragma once // NOLINT(build/header_guard)
#include "AgoraBase.h"
#ifndef OPTIONAL_ENUM_CLASS
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
#define OPTIONAL_ENUM_CLASS enum class
#else
#define OPTIONAL_ENUM_CLASS enum
#endif
#endif
namespace agora {
namespace rtc {
/**
* This structure defines the video frame of texture type on Android
* @note For technical preview, not supported for the moment. Use RawPixelBuffer instead.
*
*/
struct TextureInfo {
OPTIONAL_ENUM_CLASS TextureType {
kGlTextureOes,
kGlTexture2D,
};
OPTIONAL_ENUM_CLASS EglContextType {
kEglContext10,
kEglContext14,
};
TextureType texture_type;
EglContextType context_type;
void* shared_context;
int texture_id;
int64_t fence_object;
float transform_matrix[16];
};
/**
* This structure defines the raw video frame data in memory
*
*/
struct RawPixelBuffer {
OPTIONAL_ENUM_CLASS Format {
kUnknown,
kI420,
kI422,
kNV21,
kNV12,
kI010,
kRGBA,
kARGB,
kBGRA
};
Format format;
uint8_t* data;
int size;
};
struct PaddedRawPixelBuffer {
RawPixelBuffer::Format format;
uint8_t* data;
int size;
int stride;
PaddedRawPixelBuffer()
: data(NULL), size(0), stride(0) {}
};
/**
* This structure defines underlying detailed video frame data of @ref agora::rtc::IVideoFrame
*
*/
struct VideoFrameData {
OPTIONAL_ENUM_CLASS Type {
kRawPixels, // Raw pixels in memory
kTexture, // Deprecated Android: GL_TEXTURE_2D/GL_TEXTURE_OES
kCVPixelBuffer, // iOS: CVPixelBufferRef
kPaddedRawPixels, // Raw pixels with paddings
kTextureOES,// Android: GL_TEXTURE_OES
kTexture2D, // Android: GL_TEXTURE_2D
};
Type type;
union {
TextureInfo texture; // Android (To be supported)
RawPixelBuffer pixels; // All platform
void* cvpixelbuffer; // iOS (To be supported)
};
int width;
int height;
int rotation;
agora::media::base::ColorSpace color_space;
int64_t timestamp_ms; // Capture time in milli-seconds
};
struct VideoFrameDataV2 : public VideoFrameData {
PaddedRawPixelBuffer padded_pixels; // All platform
};
OPTIONAL_ENUM_CLASS VideoFrameMetaDataType {
kAlphaChannel,
kScreenMetaInfo,
kVideoSourceType,
kFaceInfo,
kFaceCaptureInfo,
// Add other types afterwards
};
struct AlphaChannel {
uint8_t* data;
int size;
};
typedef int32_t VideoSourceType;
/**
* The IVideoFrame class defines the interface to
* send video frame data to the SDK or get video frame data from the SDK.
*/
class IVideoFrame : public RefCountInterface {
public:
/**
* Get the concrete video frame data of the underlying buffer.
* @param data [out] The video frame data.
* @return
* - int: error code. 0 for success.
*/
virtual int getVideoFrameData(VideoFrameData& data) const = 0;
/**
* Fill the underlying buffer with source buffer info contained in VideoFrameData
* For frames of type "Type::kMemPixels", This function first tries to fill in-place with no copy and reallocation.
* When it fails, a copy or copy-plus-reallocation may happen
* @param data [in] Data to be filled in.
* @return
* - 0: if succeeds
* - <0: failure
*/
virtual int fillVideoFrameData(const VideoFrameData& data) = 0;
/**
* Get the underlying meta data of the given type.
* e.g. If type is VideoFrameMetaDataType::kAlphaChannel, then data value can be casted to AlphaChannel;
* @param type @ref VideoFrameMetaDataType type of the meta data wanted
* @param data [out] pointer to the the meta data object of the given type
* @return
* - 0: if succeeds
* - <0: failure
*/
virtual int getVideoFrameMetaData(VideoFrameMetaDataType type, void* data) = 0;
/**
* Fill the underlying meta data of the given type.
* e.g. If type is VideoFrameMetaDataType::kAlphaChannel, then data should point to AlphaChannel object;
* @param type @ref VideoFrameMetaDataType type of the meta data to fill
* @param data [in] pointer to the the meta data object of the given type
* @return
* - 0: if succeeds
* - <0: failure
*/
virtual int fillVideoFrameMetaData(VideoFrameMetaDataType type, const void* data) = 0;
protected:
~IVideoFrame() {}
};
class IVideoFrameMemoryPool : public RefCountInterface {
public:
/**
* Create IVideoFrame
* @param data video frame data of the new video frame
* @param metatypes pointer to the array of meta types
* @param count number of the meta types in the array
*/
virtual agora::agora_refptr<IVideoFrame> createVideoFrame(
const VideoFrameData& data, const VideoFrameMetaDataType* metatypes = NULL, int count = 0) = 0;
protected:
virtual ~IVideoFrameMemoryPool() {}
};
} // namespace rtc
} // namespace agora

View File

@@ -0,0 +1,159 @@
//
// Agora SDK
//
// Copyright (c) 2018 Agora.io. All rights reserved.
//
#pragma once // NOLINT(build/header_guard)
#include "AgoraBase.h"
#include "AgoraRefPtr.h"
#include "IAgoraService.h"
namespace agora {
namespace rtc {
class IVideoTrack;
struct MixerLayoutConfig {
int32_t x;
int32_t y;
int32_t width;
int32_t height;
int32_t zOrder; // larger zOrder prioritizes smaller ones
float alpha;
bool mirror;
const char* image_path; // url of the place holder picture
MixerLayoutConfig() : x(0), y(0), width(0), height(0), zOrder(0), alpha(1.0), mirror(false), image_path(NULL) {}
MixerLayoutConfig(int ox, int oy, int w, int h, int order) : x(ox), y(oy), width(w), height(h), zOrder(order), alpha(1.0), mirror(false), image_path(NULL) {}
};
enum ImageType {
kPng,
kJpeg,
kGif
};
/**
* The IVideoMixerSource class abstracts a multi-in-multi-out video source which receives video
* streams from multiple local or remote video tracks and generate mixed video stream in user defined output
* format. When only one video track is added to the mixer, it simply forwards the incoming video frames
* to its sinks.
*/
class IVideoMixerSource : public RefCountInterface {
public:
/**
* Add a video track for mixing.
* @param id The unique id of the stream.
* @param track The instance of the video track that you want mixer to receive its video stream.
* @return
* 0 - Success
* <0 - Failure
*/
virtual int addVideoTrack(const char* id, agora_refptr<IVideoTrack> track, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Remove the video track.
* @param id The unique id of the stream.
* @param track The instance of the video track that you want to remove from the mixer.
* @return
* 0 - Success
* <0 - Failure
*/
virtual int removeVideoTrack(const char* id, agora_refptr<IVideoTrack> track, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Configures the layout of video frames comming from a specific track (indicated by uid)
* on the mixer canvas.
* @param id The unique id of the stream.
* @param config The layout configuration
* @return
* 0 - Success
* <0 - Failure
*/
virtual int setStreamLayout(const char* id, const MixerLayoutConfig& config, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Remove the user layout on the mixer canvas
* @param id The unique id of the stream.
* @param uid The uid of the stream.
* @return
* 0 - Success
* <0 - Failure
*/
virtual int delStreamLayout(const char* id, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Add a image source to the mixer with its layout configuration on the mixer canvas.
* @param id The unique id of the image.
* @param config The layout configuration
* @return
* 0 - Success
* <0 - Failure
*/
virtual int addImageSource(const char* id, const MixerLayoutConfig& config, ImageType type = kPng, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Delete a image source to the mixer.
* @param id The unique id of the image.
* @return
* 0 - Success
* <0 - Failure
*/
virtual int delImageSource(const char* id, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Clear all the layout settings set previously
*/
virtual int clearLayout(aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Refresh the user layout on the mixer canvas
* @return
* 0 - Success
* <0 - Failure
*/
virtual int refresh(aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Set the mixer canvas background to override the default configuration
* @param width width of the canvas
* @param height height of the canvas
* @param fps fps of the mixed video stream
* @param color_argb mixer canvas background color in argb
* @return
* 0 - Success
* <0 - Failure
*/
virtual int setBackground(uint32_t width, uint32_t height, int fps, uint32_t color_argb = 0, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Set the mixer canvas background to override the default configuration
* @param width width of the canvas
* @param height height of the canvas
* @param fps fps of the mixed video stream
* @param url URL of the canvas background image
* @return
* 0 - Success
* <0 - Failure
*/
virtual int setBackground(uint32_t width, uint32_t height, int fps, const char* url, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Set the rotation of the mixed video stream
* @param rotation:0:none, 1:90°, 2:180°, 3:270°
* @return
* 0 - Success
* <0 - Failure
*/
virtual int setRotation(uint8_t rotation, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Get the average delay in ms introduced by the mixer module, which includes the average
* mixing delay plus the encoder delay.
* @return
* delay in ms
*/
virtual int getAvgMixerDelay() = 0;
/**
* Set the master clock source for mixed video frame. The master clock source serves as the
* reference clock for audio/video synchronization after mixing.
* @return
* 0 - Success
* <0 - Failure
*/
virtual int setMasterClockSource(const char* id = NULL, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
};
} //namespace rtc
} // namespace agora

View File

@@ -0,0 +1,620 @@
// Copyright (c) 2019 Agora.io. All rights reserved
// This program is confidential and proprietary to Agora.io.
// And may not be copied, reproduced, modified, disclosed to others, published
// or used, in whole or in part, without the express prior written permission
// of Agora.io.
#pragma once // NOLINT(build/header_guard)
#include "AgoraBase.h"
#include <aosl/api/aosl_ref.h>
#ifndef OPTIONAL_OVERRIDE
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
#define OPTIONAL_OVERRIDE override
#else
#define OPTIONAL_OVERRIDE
#endif
#endif
namespace agora {
namespace rtc {
class IVideoFilter;
class IVideoEncodedFrameObserver;
class IMediaPacketReceiver;
class IVideoSinkBase;
enum StreamLayerIndexInternal {
STREAM_LAYER_1 = 1,
STREAM_LAYER_2 = 2,
STREAM_LAYER_3 = 3,
STREAM_LAYER_4 = 4,
STREAM_LAYER_5 = 5,
STREAM_LAYER_6 = 6,
STREAM_LOW = 7,
STREAM_LAYER_COUNT_MAX = 8
};
struct StreamLayerConfigInternal {
VideoDimensions dimensions;
int framerate;
int bitrate_kbps;
bool enable;
StreamLayerConfigInternal() : dimensions(0, 0), framerate(0), bitrate_kbps(STANDARD_BITRATE), enable(false) {}
StreamLayerConfigInternal(const StreamLayerConfigInternal& other) : dimensions(other.dimensions), framerate(other.framerate), bitrate_kbps(other.bitrate_kbps), enable(other.enable) {}
bool operator==(const StreamLayerConfigInternal& rhs) const {
return dimensions == rhs.dimensions && bitrate_kbps == rhs.bitrate_kbps && framerate == rhs.framerate && enable == rhs.enable;
}
StreamLayerConfigInternal& operator=(const SimulcastConfig::StreamLayerConfig& slc) {
dimensions = slc.dimensions;
framerate = slc.framerate;
enable = slc.enable;
return *this;
}
void reset() {
dimensions.width = 0;
dimensions.height = 0;
framerate = 0;
bitrate_kbps = STANDARD_BITRATE;
enable = false;
}
};
struct SimulcastConfigInternal {
StreamLayerConfigInternal simulcastlayerConfigs[STREAM_LAYER_COUNT_MAX];
void reset() {
for (int i = STREAM_LAYER_1; i < STREAM_LAYER_COUNT_MAX; i++) {
simulcastlayerConfigs[i].reset();
}
}
bool operator==(const SimulcastConfigInternal& rhs) const {
for (int i = 0; i < STREAM_LAYER_COUNT_MAX; i++) {
if (simulcastlayerConfigs[i] == rhs.simulcastlayerConfigs[i]) {
continue;
} else {
return false;
}
}
return true;
}
};
enum VideoTrackType {
LOCAL_VIDEO_TRACK,
REMOTE_VIDEO_TRACK,
REMOTE_VIDEO_IMAGE_TRACK,
};
/**
* The `IVideoTrack` class defines the behavior and status of a video track.
*/
class IVideoTrack : public RefCountInterface {
public:
/**
* Adds a video filter to the video track.
*
* Add a video filter in either of the following ways:
* - Use the \ref agora::rtc::IMediaNodeFactory "IMediaNodeFactory" object to create a built-in video filter.
* - Use a custom video filter by implementing the \ref agora::rtc::IVideoFilter "IVideoFilter" class.
*
* To add multiple filters, call this method multiple times. The order of the added filters depends on when
* the app successfully adds the filter.
*
* @param filter The video filter that you want to add to the video track.
* @param position The position where the filter is added.
* @param id id of the filter
* @return
* - `true`: The video filter is added successfully.
* - `false`: The video filter fails to be added.
*/
virtual bool addVideoFilter(
agora_refptr<IVideoFilter> filter, media::base::VIDEO_MODULE_POSITION position = media::base::POSITION_POST_CAPTURER,
const char* id = NULL, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Removes the video filter added by `addVideoFilter` from the video track.
*
* @param filter The video filter that you want to remove: `IVideoFilter`.
* @param position The position of the filter.
* @id id of the filter
* @return
* - `true`: The video filter is removed successfully.
* - `false`: The video filter fails to be removed.
*/
virtual bool removeVideoFilter(
agora_refptr<IVideoFilter> filter, media::base::VIDEO_MODULE_POSITION position = media::base::POSITION_POST_CAPTURER,
const char* id = NULL, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Whether a video filter exists
* @param id id of the filter
* @return
* - true: exist
* - false: not exist
*/
virtual bool hasVideoFilter(const char* id, media::base::VIDEO_MODULE_POSITION position = media::base::POSITION_POST_CAPTURER) = 0;
/**
* Adds a video renderer to the video track.
*
* Add a video renderer in either of the following ways:
* - Use the built-in video renderer by implementing the `IVideoRenderer` in the `IMediaNodeFactory` class.
* - Use a custom video renderer by implementing the `IVideoSinkBase` class.
*
* @param videoRenderer The video renderer that you want to add: IVideoSinkBase.
* @param position The position where the renderer is added.
*
* @return
* - `true`: The video renderer is added successfully.
* - `false`: The video renderer fails to be added.
*/
virtual bool addRenderer(agora_refptr<IVideoSinkBase> videoRenderer, media::base::VIDEO_MODULE_POSITION position, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Removes the video renderer added by `addRenderer` from the video track.
*
* @param videoRenderer The video renderer that you want to remove: IVideoSinkBase.
* @param position The position where the renderer is removed: \ref media::base::VIDEO_MODULE_POSITION "VIDEO_MODULE_POSITION".
* @return
* - `true`: The video renderer is removed successfully.
* - `false`: The video renderer fails to be removed.
*/
virtual bool removeRenderer(agora_refptr<IVideoSinkBase> videoRenderer, media::base::VIDEO_MODULE_POSITION position, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Get the track type of the video track
* @return
* - VideoTrackType
*/
virtual VideoTrackType getType() = 0;
/**
* Enable / Disable specified video filter
* @param id id of the filter
* @param enable enable / disable the filter with given id
* @return
* - 0: success
* - <0: failure
*/
virtual int enableVideoFilter(const char* id, bool enable, aosl_ref_t ares = AOSL_REF_INVALID) { return -1; }
/**
* set the properties of the specified video filter
* @param id id of the filter
* @param key key of the property
* @param json_value json str value of the property
* @return
* - 0: success
* - <0: failure
*/
virtual int setFilterProperty(const char* id, const char* key, const char* json_value, aosl_ref_t ares = AOSL_REF_INVALID) { return -1; }
/**
* get the properties of the specified video filter
* @param id id of the filter
* @param key key of the property
* @param json_value json str value of the property
* @return
* - 0: success
* - <0: failure
*/
virtual int getFilterProperty(const char* id, const char* key, char* json_value, size_t buf_size, aosl_ref_t ares = AOSL_REF_INVALID) { return -1; }
protected:
~IVideoTrack() {}
};
struct SimulcastStreamProfile {
int width;
int height;
int framerate;
int bitrate;
};
/**
* The statistics of the local video track.
*/
struct LocalVideoTrackStats {
/**
* The number of streams.
*/
uint64_t number_of_streams;
/**
* The number of bytes of the major stream.
*/
uint64_t bytes_major_stream;
/**
* The number of bytes of the minor stream.
*/
uint64_t bytes_minor_stream;
/**
* The number of encoded frames.
*/
uint32_t frames_encoded;
/**
* The SSRC (synchronization source) of the major stream.
*/
uint32_t ssrc_major_stream;
/**
* The SSRC (synchronization source) of the minor stream.
*/
uint32_t ssrc_minor_stream;
/**
* The capture frame rate of the video.
*/
int capture_frame_rate;
/**
* The regulated frame rate of capture frame rate according to video encoder configuration.
*/
int regulated_capture_frame_rate;
/**
* The input frame rate of the encoder.
*/
int input_frame_rate;
/**
* The output frame rate of the encoder.
*/
int encode_frame_rate;
/**
* The rendering frame rate.
*/
int render_frame_rate;
/**
* The target bitrate (bps).
*/
int target_media_bitrate_bps;
/**
* The frame rate excluding FEC.
*/
int media_bitrate_bps;
/**
* The total frame rate including FEC.
*/
int total_bitrate_bps; // Include FEC
/**
* The capture frame width (pixel).
*/
int capture_width;
/**
* The capture frame height (pixel).
*/
int capture_height;
/**
* The regulated frame width (pixel) of capture frame width according to video encoder configuration.
*/
int regulated_capture_width;
/**
* The regulated frame height (pixel) of capture frame height according to video encoder configuration.
*/
int regulated_capture_height;
/**
* The frame width (pixel).
*/
int width;
/**
* The frame height (pixel).
*/
int height;
uint32_t encoder_type;
uint32_t hw_encoder_accelerating;
/*
* encoder vender id, VideoCodecVenderId
*/
uint32_t encoder_vender_id;
/**
* The average time diff between frame captured and framed encoded.
*/
uint32_t uplink_cost_time_ms;
/** Quality change of the local video in terms of target frame rate and
* target bit rate in this reported interval. See #QUALITY_ADAPT_INDICATION.
*/
QUALITY_ADAPT_INDICATION quality_adapt_indication;
/**
* The video packet loss rate (%) from the local client to the Agora edge server before applying the anti-packet loss strategies.
*/
unsigned short txPacketLossRate;
/** The brightness level of the video image captured by the local camera. See #CAPTURE_BRIGHTNESS_LEVEL_TYPE.
*/
CAPTURE_BRIGHTNESS_LEVEL_TYPE capture_brightness_level;
SimulcastStreamProfile simulcast_stream_profile[STREAM_LAYER_COUNT_MAX];
LocalVideoTrackStats() : number_of_streams(0),
bytes_major_stream(0),
bytes_minor_stream(0),
frames_encoded(0),
ssrc_major_stream(0),
ssrc_minor_stream(0),
capture_frame_rate(0),
regulated_capture_frame_rate(0),
input_frame_rate(0),
encode_frame_rate(0),
render_frame_rate(0),
target_media_bitrate_bps(0),
media_bitrate_bps(0),
total_bitrate_bps(0),
capture_width(0),
capture_height(0),
regulated_capture_width(0),
regulated_capture_height(0),
width(0),
height(0),
encoder_type(0),
hw_encoder_accelerating(0),
encoder_vender_id(0),
uplink_cost_time_ms(0),
quality_adapt_indication(ADAPT_NONE),
txPacketLossRate(0),
capture_brightness_level(CAPTURE_BRIGHTNESS_LEVEL_INVALID) {}
};
/**
* `ILocalVideoTrack` is the basic class for local video tracks, providing the main methods of local video tracks.
* You can create a local video track by calling one of the following methods:
* - `createCameraVideoTrack`
* - `createScreenVideoTrack`
* - `createMixedVideoTrack`
* - `createCustomVideoTrack`
* - `createMediaPlayerVideoTrack`
*
* After creating local video tracks, you can publish one or more local video tracks by calling \ref agora::rtc::ILocalUser::publishVideo "publishVideo".
*/
class ILocalVideoTrack : public IVideoTrack {
public:
/**
* Enables or disables the local video track.
*
* Once the local video track is enabled, the SDK allows for local video capturing, processing, and encoding.
*
* @param enable Determines whether to enable the local video track.
* - `true`: Enable the local video track.
* - `false`: Disable the local video track.
*/
virtual int setEnabled(bool enable, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Sets the video encoder configuration.
*
* Each video encoder configuration corresponds to a set of video parameters, including the
* resolution, frame rate, bitrate, and video orientation.
*
* The configurations specified in this method are the maximum values under ideal network conditions. If
* the video engine cannot render the video using the specified parameters due to poor network
* conditions, the configurations further down the list are considered until a successful configuration
* is found.
*
* @param config The reference to the video encoder configuration. See \ref agora::rtc::VideoEncoderConfiguration "VideoEncoderConfiguration".
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setVideoEncoderConfiguration(const VideoEncoderConfiguration& config, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Set simulcast stream mode, enable, disable or auto enable
*
* @param mode Determines simulcast stream mode. See \ref agora::rtc::SIMULCAST_STREAM_MODE "SIMULCAST_STREAM_MODE".
* @param config The reference to the configurations for the simulcast stream mode. See \ref agora::rtc::SimulcastStreamConfig "SimulcastStreamConfig".
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int setSimulcastStreamMode(SIMULCAST_STREAM_MODE mode, const SimulcastConfigInternal& config, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Gets the state of the local video stream.
*
* @return The current state of the local video stream.
*/
virtual LOCAL_VIDEO_STREAM_STATE getState() = 0;
/**
* Gets the statistics of the local video track.
*
* @param[out] stats The reference to the statistics of the local video track.
* @return
* - `true`: Success.
* - `false`: Failure.
*/
virtual bool getStatistics(LocalVideoTrackStats& stats) = 0;
virtual VideoTrackType getType() OPTIONAL_OVERRIDE { return LOCAL_VIDEO_TRACK; }
protected:
~ILocalVideoTrack() {}
};
/**
* The struct of RemoteVideoTrackStats.
*/
struct RemoteVideoTrackStats {
/**
The ID of the remote user.
*/
uid_t uid;
/**
* The overall delay (ms) of the video frames.
*/
int delay;
/**
* End-to-end delay from video capturer to video renderer. Hardware capture or render delay is excluded.
*/
int e2eDelay;
/**
* The width (pixel) of the remote video track.
*/
int width;
/**
* The height (pixel) of the remote video track.
*/
int height;
/**
* The bitrate (Kbps) received in the reported interval.
*/
int receivedBitrate;
/** The decoder input frame rate (fps) of the remote video track.
*/
int decoderInputFrameRate;
/** The decoder output frame rate (fps) of the remote video track.
*/
int decoderOutputFrameRate;
/** The render output frame rate (fps) of the remote video track.
*/
int rendererOutputFrameRate;
/** The video frame loss rate (%) of the remote video stream in the reported interval.
*/
int frameLossRate;
/** The packet loss rate (%) of the remote video track after using the anti-packet-loss method.
*/
int packetLossRate;
/**
* The remote video stream type: #VIDEO_STREAM_TYPE.
*/
VIDEO_STREAM_TYPE rxStreamType;
/**
The total freeze time (ms) of the remote video track after the remote user joins the channel.
In a video session where the frame rate is set to no less than 5 fps, video freeze occurs when
the time interval between two adjacent renderable video frames is more than 500 ms.
*/
int totalFrozenTime;
/**
The total video freeze time as a percentage (%) of the total time when the video is available.
*/
int frozenRate;
/**
* The number of video bytes received.
*/
uint32_t received_bytes;
/**
The total number of decoded video frames.
*/
uint32_t totalDecodedFrames;
/**
The offset (ms) between audio and video stream. A positive value indicates the audio leads the
video, and a negative value indicates the audio lags the video.
*/
int avSyncTimeMs;
/**
The average offset(ms) between receive first packet which composite the frame and the frame
ready to render.
*/
uint32_t downlink_process_time_ms;
/**
The average time cost in renderer.
*/
uint32_t frame_render_delay_ms;
/**
The total time (ms) when the remote user neither stops sending the video
stream nor disables the video module after joining the channel.
*/
uint64_t totalActiveTime;
/**
The total publish duration (ms) of the remote video stream.
*/
uint64_t publishDuration;
/**
decoded frame vqa mos value after all filter.
*/
int vqa_mos;
/**
vqa avg cost ms
*/
int vqa_avg_cost_ms;
/**
decoder vender id, VideoCodecVenderId
*/
uint32_t decoder_vender_id;
/**
The decoder codec type of the remote video track
*/
uint32_t decoder_type;
RemoteVideoTrackStats() : uid(0), delay(0), width(0), height(0),
receivedBitrate(0), decoderInputFrameRate(0), decoderOutputFrameRate(0), rendererOutputFrameRate(0),
frameLossRate(0), packetLossRate(0), rxStreamType(VIDEO_STREAM_HIGH),
totalFrozenTime(0), frozenRate(0), received_bytes(0), totalDecodedFrames(0), avSyncTimeMs(0),
downlink_process_time_ms(0), frame_render_delay_ms(0), totalActiveTime(0),
publishDuration(0), vqa_mos(0), vqa_avg_cost_ms(0), decoder_vender_id(0), decoder_type(0) {}
};
/**
* The IRemoteVideoTrack class.
*/
class IRemoteVideoTrack : public IVideoTrack {
public:
/**
* Gets the statistics of the remote video track.
* @param[out] stats The reference to the statistics of the remote video track.
* @return
* - `true`: Success.
* - `false`: Failure.
*/
virtual bool getStatistics(RemoteVideoTrackStats& stats) = 0;
/**
* Gets the state of the remote video track.
* @return The state of the remote video track.
*/
virtual REMOTE_VIDEO_STATE getState() = 0;
/**
* Gets the information of the remote video track.
* @param[out] info The reference to the information of the remote video track.
* @return
* - `true`: Success.
* - `false`: Failure.
*/
virtual bool getTrackInfo(VideoTrackInfo& info) = 0;
/**
* Registers an \ref agora::media::IVideoEncodedFrameObserver "IVideoEncodedFrameObserver" object.
*
* You need to implement the `IVideoEncodedFrameObserver` class in this method. Once you successfully register
* the encoded image receiver, the SDK triggers the \ref agora::rtc::IVideoEncodedFrameObserver::onEncodedVideoFrameReceived "onEncodedVideoFrameReceived" callback when it receives the
* encoded video image.
*
* @param encodedObserver The pointer to the `IVideoEncodedFrameObserver` object.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int registerVideoEncodedFrameObserver(agora::media::IVideoEncodedFrameObserver* encodedObserver, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Releases the \ref agora::media::IVideoEncodedFrameObserver "IVideoEncodedFrameObserver" object.
* @param encodedObserver The pointer to the `IVideoEncodedFrameObserver` object.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int unregisterVideoEncodedFrameObserver(agora::media::IVideoEncodedFrameObserver* encodedObserver) = 0;
/**
* Registers an \ref agora::rtc::IMediaPacketReceiver "IMediaPacketReceiver" object.
*
* You need to implement the `IMediaPacketReceiver` class in this method. Once you successfully register
* the media packet receiver, the SDK triggers the \ref agora::rtc::IMediaPacketReceiver::onMediaPacketReceived "onMediaPacketReceived" callback when it receives the
* video packet.
*
* @param videoReceiver The pointer to the `IMediaPacketReceiver` object.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int registerMediaPacketReceiver(IMediaPacketReceiver* videoReceiver, aosl_ref_t ares = AOSL_REF_INVALID) = 0;
/**
* Releases the \ref agora::rtc::IMediaPacketReceiver "IMediaPacketReceiver" object.
* @param videoReceiver The pointer to the `IMediaPacketReceiver` object.
* @return
* - 0: Success.
* - < 0: Failure.
*/
virtual int unregisterMediaPacketReceiver(IMediaPacketReceiver* videoReceiver) = 0;
virtual VideoTrackType getType() OPTIONAL_OVERRIDE { return REMOTE_VIDEO_TRACK; }
protected:
~IRemoteVideoTrack() {}
};
} // namespace rtc
} // namespace agora

View File

@@ -0,0 +1,85 @@
//
// Agora Media SDK
//
// Copyright (c) 2021 Agora IO. All rights reserved.
//
#pragma once
#include <stdint.h>
namespace agora {
namespace base {
class NtpTime {
public:
static const uint64_t ntpFracPerSecond = 4294967296;
NtpTime() : ms_(0) {}
NtpTime(uint64_t ms) : ms_(ms) {}
NtpTime(uint32_t seconds, uint32_t fractions) {
const double fracMs = fractions * 1000.0 / static_cast<double>(ntpFracPerSecond);
ms_ = static_cast<uint64_t>(seconds) * 1000 + static_cast<uint64_t>(0.5 + fracMs);
}
operator uint64_t() const { return ms_; }
/** Gets the NTP time.
*
* @return
* - The wallclock time which is in milliseconds relative to 0h UTC on 1 January 1900.
*/
uint64_t Ms() const {
return ms_;
}
/** Check that whether the NtpTime object is valid
*
* - `true`: the NtpTime object is valid.
* - `false`: the NtpTime object is invalid.
*/
bool Valid() const { return ms_ != 0; }
/** Gets the integer part of the NTP timestamp.
*
* @return
* - An uint32_t value.
*/
uint32_t ToSeconds() const {
return static_cast<uint32_t>(ms_ / 1000);
}
/** Gets the fractional part of the NTP timestamp.
*
* @return
* - An uint32_t value.
*/
uint32_t ToFractions() const {
return static_cast<uint32_t>((ms_ % 1000) * static_cast<double>(ntpFracPerSecond) / 1000.0);
}
/** Gets the NTP timestamp.
*
* @note
* - The full resolution NTP timestamp is a 64-bit unsigned fixed-point number with the integer part in the first 32 bits and the fractional part in the last 32 bits.
*
* @return
* - An uint64_t value.
*/
uint64_t ToTimestamp() const {
return ToSeconds() * ntpFracPerSecond + ToFractions();
}
private:
uint64_t ms_;
};
inline bool operator==(const NtpTime& n1, const NtpTime& n2) {
return static_cast<uint64_t>(n1) == static_cast<uint64_t>(n2);
}
inline bool operator!=(const NtpTime& n1, const NtpTime& n2) { return !(n1 == n2); }
} // namespace base
} // namespace agora

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>AgoraRtcKit</string>
<key>CFBundleIdentifier</key>
<string>io.agora.AgoraRtcKit</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>AgoraRtcKit</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>4.5.2</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>iPhoneOS</string>
</array>
<key>CFBundleVersion</key>
<string>1</string>
<key>MinimumOSVersion</key>
<string>9.0</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright (c) 2014-2025 Agora. All rights reserved.</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

View File

@@ -0,0 +1,112 @@
framework module AgoraRtcKit {
header "AgoraRtcKit.h"
module AgoraConstants {
header "AgoraConstants.h"
export *
}
module AgoraEnumerates {
header "AgoraEnumerates.h"
export *
}
module AgoraObjects {
header "AgoraObjects.h"
export *
}
module AgoraRtcEngineKit {
header "AgoraRtcEngineKit.h"
export *
}
module AgoraRtcEngineKitEx {
header "AgoraRtcEngineKitEx.h"
export *
}
module AgoraRtcEngineDelegate {
header "AgoraRtcEngineDelegate.h"
export *
}
module AgoraAudioFrameDelegate {
header "AgoraAudioFrameDelegate.h"
export *
}
module AgoraAudioEncodedFrameDelegate {
header "AgoraAudioEncodedFrameDelegate.h"
export *
}
module AgoraRtcAudioSpectrumDelegate {
header "AgoraRtcAudioSpectrumDelegate.h"
export *
}
module AgoraVideoFrameDelegate {
header "AgoraVideoFrameDelegate.h"
export *
}
module AgoraFaceInfoDelegate {
header "AgoraFaceInfoDelegate.h"
export *
}
module AgoraEncodedVideoFrameDelegate {
header "AgoraEncodedVideoFrameDelegate.h"
export *
}
module AgoraRtcMediaPlayerProtocol {
header "AgoraRtcMediaPlayerProtocol.h"
export *
}
module AgoraRtcMediaPlayerDelegate {
header "AgoraRtcMediaPlayerDelegate.h"
export *
}
module AgoraRtcMediaPlayerAudioFrameDelegate {
header "AgoraRtcMediaPlayerAudioFrameDelegate.h"
export *
}
module AgoraRtcMediaPlayerVideoFrameDelegate {
header "AgoraRtcMediaPlayerVideoFrameDelegate.h"
export *
}
module AgoraH265TranscoderProtocol {
header "AgoraH265TranscoderProtocol.h"
export *
}
module AgoraH265TranscoderDelegate {
header "AgoraH265TranscoderDelegate.h"
export *
}
module AgoraMediaRecorder {
header "AgoraMediaRecorder.h"
export *
}
module AgoraMediaRecorderDelegate {
header "AgoraMediaRecorderDelegate.h"
export *
}
module AgoraMediaMetadataDelegate {
header "AgoraMediaMetadataDelegate.h"
export *
}
module AgoraMediaMetadataDataSource {
header "AgoraMediaMetadataDataSource.h"
export *
}
module AgoraDirectCdnStreamingEventDelegate {
header "AgoraDirectCdnStreamingEventDelegate.h"
export *
}
module AgoraMediaFilterEventDelegate {
header "AgoraMediaFilterEventDelegate.h"
export *
}
module AgoraSpatialAudioKit {
header "AgoraSpatialAudioKit.h"
export *
}
module AgoraMusicContentCenter {
header "AgoraMusicContentCenter.h"
export *
}
module AgoraRtcMediaPlayerCacheManagerProtocol {
header "AgoraRtcMediaPlayerCacheManagerProtocol.h"
export *
}
export *
}

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyCollectedDataTypes</key>
<array/>
<key>NSPrivacyTracking</key>
<false/>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>35F9.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>DDA9.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>E174.1</string>
</array>
</dict>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,73 @@
// Copyright (c) 2020 Agora.io. All rights reserved
// This program is confidential and proprietary to Agora.io.
// And may not be copied, reproduced, modified, disclosed to others, published
// or used, in whole or in part, without the express prior written permission
// of Agora.io.
#pragma once
#if defined(_WIN32)
// clang-format off
// clang formating would change include order.
// Include WinSock2.h before including <Windows.h> to maintain consistency with
// win32.h. To include win32.h directly, it must be broken out into its own
// build target.
#include <WinSock2.h>
#include <Windows.h>
// clang-format on
#endif // _WIN32
namespace agora {
class AtomicOps {
public:
#if defined(_WIN32)
// Assumes sizeof(int) == sizeof(LONG), which it is on Win32 and Win64.
static int Increment(volatile int* i) {
return ::InterlockedIncrement(reinterpret_cast<volatile LONG*>(i));
}
static int Decrement(volatile int* i) {
return ::InterlockedDecrement(reinterpret_cast<volatile LONG*>(i));
}
static int AcquireLoad(volatile const int* i) { return *i; }
static void ReleaseStore(volatile int* i, int value) { *i = value; }
static int CompareAndSwap(volatile int* i, int old_value, int new_value) {
return ::InterlockedCompareExchange(reinterpret_cast<volatile LONG*>(i),
new_value, old_value);
}
// Pointer variants.
template <typename T>
static T* AcquireLoadPtr(T* volatile* ptr) {
return *ptr;
}
template <typename T>
static T* CompareAndSwapPtr(T* volatile* ptr, T* old_value, T* new_value) {
return static_cast<T*>(::InterlockedCompareExchangePointer(
reinterpret_cast<PVOID volatile*>(ptr), new_value, old_value));
}
#else
static int Increment(volatile int* i) { return __sync_add_and_fetch(i, 1); }
static int Decrement(volatile int* i) { return __sync_sub_and_fetch(i, 1); }
static int AcquireLoad(volatile const int* i) {
return __atomic_load_n(i, __ATOMIC_ACQUIRE);
}
static void ReleaseStore(volatile int* i, int value) {
__atomic_store_n(i, value, __ATOMIC_RELEASE);
}
static int CompareAndSwap(volatile int* i, int old_value, int new_value) {
return __sync_val_compare_and_swap(i, old_value, new_value);
}
// Pointer variants.
template <typename T>
static T* AcquireLoadPtr(T* volatile* ptr) {
return __atomic_load_n(ptr, __ATOMIC_ACQUIRE);
}
template <typename T>
static T* CompareAndSwapPtr(T* volatile* ptr, T* old_value, T* new_value) {
return __sync_val_compare_and_swap(ptr, old_value, new_value);
}
#endif // _WIN32
};
} // namespace agora

View File

@@ -0,0 +1,36 @@
//
// AgoraRtcEngineKit.h
// AgoraRtcEngineKit
//
// Copyright (c) 2018 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "AgoraConstants.h"
#import "AgoraObjects.h"
/** Agora provides ensured quality of experience (QoE) for worldwide Internet-based voice and video communications through a virtual global network that is especially optimized for real-time web and mobile-to-mobile applications.
The AgoraRtcEngineKit class is the entry point of the Agora SDK that provides simple APIs for applications to easily start voice and video communication.
*/
@class AgoraRtcEngineKit;
@class AgoraMediaRecorder;
@protocol AgoraAudioEncodedFrameDelegate <NSObject>
@required
/**
* Occurs when the record audio data is received.
*/
- (void)onRecordEncodedAudioFrame:(NSData* _Nonnull)frameData info:(AgoraEncodedAudioFrameInfo* _Nonnull)info NS_SWIFT_NAME(onRecordEncodedAudioFrame(_:info:));
/**
* Occurs when the playback audio data is received.
*/
- (void)onPlaybackEncodedAudioFrame:(NSData* _Nonnull)frameData info:(AgoraEncodedAudioFrameInfo* _Nonnull)info NS_SWIFT_NAME(onPlaybackEncodedAudioFrame(_:info:));
/**
* Occurs when the mixed audio data is received.
*/
- (void)onMixedEncodedAudioFrame:(NSData* _Nonnull)frameData info:(AgoraEncodedAudioFrameInfo* _Nonnull)info NS_SWIFT_NAME(onMixedEncodedAudioFrame(_:info:));
@end

View File

@@ -0,0 +1,204 @@
//
// AgoraRtcEngineKit.h
// AgoraRtcEngineKit
//
// Copyright (c) 2018 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "AgoraEnumerates.h"
@class AgoraAudioFrame;
@class AgoraAudioParams;
/**
* The AgoraAudioFrameDelegate protocol enables audio frame callback event notifications to your application.
*/
@protocol AgoraAudioFrameDelegate <NSObject>
@optional
/**
* Occurs when the recorded audio frame is received.
* @param frame A pointer to the audio frame: AgoraAudioFrame.
* @param channelId Unique channel name for the AgoraRTC session in the string
* format. The string length must be less than 64 bytes. Supported character
* scopes are:
* - All lowercase English letters: a to z.
* - All uppercase English letters: A to Z.
* - All numeric characters: 0 to 9.
* - The space character.
* - Punctuation characters and other symbols, including: "!", "#", "$", "%", "&", "(", ")", "+", "-", ":", ";", "<", "=", ".", ">", "?", "@", "[", "]", "^", "_", " {", "}", "|", "~", ",".
* @return
* - true: The recorded audio frame is valid and is encoded and sent.
* - false: The recorded audio frame is invalid and is not encoded or sent.
*/
- (BOOL)onRecordAudioFrame:(AgoraAudioFrame* _Nonnull)frame channelId:(NSString * _Nonnull)channelId NS_SWIFT_NAME(onRecordAudioFrame(_:channelId:));
/**
* Occurs when the playback audio frame is received.
* @param channelId Unique channel name for the AgoraRTC session in the string
* format. The string length must be less than 64 bytes. Supported character
* scopes are:
* - All lowercase English letters: a to z.
* - All uppercase English letters: A to Z.
* - All numeric characters: 0 to 9.
* - The space character.
* - Punctuation characters and other symbols, including: "!", "#", "$", "%", "&", "(", ")", "+", "-", ":", ";", "<", "=", ".", ">", "?", "@", "[", "]", "^", "_", " {", "}", "|", "~", ",".
* @param frame A pointer to the audio frame: AgoraAudioFrame.
* @return
* - true: The playback audio frame is valid and is encoded and sent.
* - false: The playback audio frame is invalid and is not encoded or sent.
*/
- (BOOL)onPlaybackAudioFrame:(AgoraAudioFrame* _Nonnull)frame channelId:(NSString * _Nonnull)channelId NS_SWIFT_NAME(onPlaybackAudioFrame(_:channelId:));
/**
* Occurs when the mixed audio data is received.
* @param frame The A pointer to the audio frame: AgoraAudioFrame.
* @param channelId Unique channel name for the AgoraRTC session in the string
* format. The string length must be less than 64 bytes. Supported character
* scopes are:
* - All lowercase English letters: a to z.
* - All uppercase English letters: A to Z.
* - All numeric characters: 0 to 9.
* - The space character.
* - Punctuation characters and other symbols, including: "!", "#", "$", "%", "&", "(", ")", "+", "-", ":", ";", "<", "=", ".", ">", "?", "@", "[", "]", "^", "_", " {", "}", "|", "~", ",".
* @return
* - true: The mixed audio data is valid and is encoded and sent.
* - false: The mixed audio data is invalid and is not encoded or sent.
*/
- (BOOL)onMixedAudioFrame:(AgoraAudioFrame* _Nonnull)frame channelId:(NSString * _Nonnull)channelId NS_SWIFT_NAME(onMixedAudioFrame(_:channelId:));
/**
* Occurs when the ear monitoring audio frame is received.
* @param frame A pointer to the audio frame: AgoraAudioFrame.
* @return
* - true: The ear monitoring audio frame is valid and is encoded and sent.
* - false: The ear monitoring audio frame is invalid and is not encoded or sent.
*/
- (BOOL)onEarMonitoringAudioFrame:(AgoraAudioFrame* _Nonnull)frame NS_SWIFT_NAME(onEarMonitoringAudioFrame(_:));
/**
Sets the frame position for the audio observer.
* @return A bit mask that controls the frame position of the audio observer.
* @note - Use '|' (the OR operator) to observe multiple frame positions.
* <p>
* After you successfully register the audio observer, the SDK triggers this callback each time it receives a audio frame. You can determine which position to observe by setting the return value.
* The SDK provides 4 positions for observer. Each position corresponds to a callback function:
* - `AgoraAudioFramePositionPlayback (1 << 0)`: The position for playback audio frame is received, which corresponds to the \ref onPlaybackFrame "onPlaybackFrame" callback.
* - `AgoraAudioFramePositionRecord (1 << 1)`: The position for record audio frame is received, which corresponds to the \ref onRecordFrame "onRecordFrame" callback.
* - `AgoraAudioFramePositionMixed (1 << 2)`: The position for mixed audio frame is received, which corresponds to the \ref onMixedFrame "onMixedFrame" callback.
* - `AgoraAudioFramePositionBeforeMixing (1 << 3)`: The position for playback audio frame before mixing is received, which corresponds to the \ref onPlaybackFrameBeforeMixing "onPlaybackFrameBeforeMixing" callback.
* @return The bit mask that controls the audio observation positions.
See AgoraAudioFramePosition.
*/
- (AgoraAudioFramePosition)getObservedAudioFramePosition NS_SWIFT_NAME(getObservedAudioFramePosition());
/** Sets the audio mixing format for the
[onMixedAudioFrame]([AgoraAudioFrameDelegate onMixedAudioFrame:]) callback.
Register the `getMixedAudioParams` callback when calling the
[setAudioFrameDelegate]([AgoraRtcEngineKit setAudioFrameDelegate:]) method. After you
successfully register the audio delegate, the SDK triggers this callback each
time it receives an audio frame. You can set the audio mixing format in
the return value of this callback.
**Note**:
- The SDK calculates the sample interval according to the `AgoraAudioParams`
you set in the return value of this callback and triggers the
`onMixedAudioFrame` callback at the calculated sample interval.
Sample interval (seconds) = `samplesPerCall`/(`sampleRate` × `channel`).
Ensure that the value of sample interval is equal to or greater than 0.01.
@return Sets the audio format. See AgoraAudioParams.
*/
- (AgoraAudioParams* _Nonnull)getMixedAudioParams NS_SWIFT_NAME(getMixedAudioParams());
/** Sets the audio recording format for the
[onRecordAudioFrame]([AgoraAudioFrameDelegate onRecordAudioFrame:])
callback.
Register the `getRecordAudioParams` callback when calling the
[setAudioFrameDelegate]([AgoraRtcEngineKit setAudioFrameDelegate:]) method. After you
successfully register the audio delegate, the SDK triggers this callback each
time it receives an audio frame. You can set the audio recording format in
the return value of this callback.
**Note**:
- This callback applies to iOS only.
- The SDK calculates the sample interval according to the `AgoraAudioParams`
you set in the return value of this callback and triggers the
`onRecordAudioFrame` callback at the calculated sample interval.
Sample interval (seconds) = `samplesPerCall`/(`sampleRate` × `channel`).
Ensure that the value of sample interval is equal to or greater than 0.01.
@return Sets the audio format. See AgoraAudioParams.
*/
- (AgoraAudioParams* _Nonnull)getRecordAudioParams NS_SWIFT_NAME(getRecordAudioParams());
/** Sets the audio playback format for the
[onPlaybackAudioFrame]([AgoraAudioFrameDelegate onPlaybackAudioFrame:])
callback.
Register the `getPlaybackAudioParams` callback when calling the
[setAudioFrameDelegate]([AgoraRtcEngineKit setAudioFrameDelegate:]) method. After you
successfully register the audio delegate, the SDK triggers this callback each
time it receives an audio frame. You can set the audio playback format in
the return value of this callback.
**Note**:
- The SDK calculates the sample interval according to the `AgoraAudioParams`
you set in the return value of this callback and triggers the
`onPlaybackAudioFrame` callback at the calculated sample interval.
Sample interval (seconds) = `samplesPerCall`/(`sampleRate` × `channel`).
Ensure that the value of sample interval is equal to or greater than 0.01.
@return Sets the audio format. See AgoraAudioParams.
*/
- (AgoraAudioParams* _Nonnull)getPlaybackAudioParams NS_SWIFT_NAME(getPlaybackAudioParams());
/** Sets the audio recording format for the
[onEarMonitoringAudioFrame]([AgoraAudioFrameDelegate onEarMonitoringAudioFrame:])
callback.
Register the `getEarMonitoringAudioParams` callback when calling the
[setAudioFrameDelegate]([AgoraRtcEngineKit setAudioFrameDelegate:]) method. After you
successfully register the audio delegate, the SDK triggers this callback each
time it receives an audio frame. You can set the audio recording format in
the return value of this callback.
**Note**:
- This callback applies to iOS only.
- The SDK calculates the sample interval according to the `AgoraAudioParams`
you set in the return value of this callback and triggers the
`onEarMonitoringAudioFrame` callback at the calculated sample interval.
Sample interval (seconds) = `samplesPerCall`/(`sampleRate` × `channel`).
Ensure that the value of sample interval is equal to or greater than 0.01.
@return Sets the audio format. See AgoraAudioParams.
*/
- (AgoraAudioParams* _Nonnull)getEarMonitoringAudioParams NS_SWIFT_NAME(getEarMonitoringAudioParams());
/**
* Occurs when the before-mixing playback audio frame is received.
* @param channelId Unique channel name for the AgoraRTC session in the string
* format. The string length must be less than 64 bytes. Supported character
* scopes are:
* - All lowercase English letters: a to z.
* - All uppercase English letters: A to Z.
* - All numeric characters: 0 to 9.
* - The space character.
* - Punctuation characters and other symbols, including: "!", "#", "$", "%", "&", "(", ")", "+", "-", ":", ";", "<", "=", ".", ">", "?", "@", "[", "]", "^", "_", " {", "}", "|", "~", ",".
* @param uid ID of the remote user.
* @param frame A pointer to the audio frame: AgoraAudioFrame.
* @return
* - true: The before-mixing playback audio frame is valid and is encoded and sent.
* - false: The before-mixing playback audio frame is invalid and is not encoded or sent.
*/
- (BOOL)onPlaybackAudioFrameBeforeMixing:(AgoraAudioFrame* _Nonnull)frame channelId:(NSString * _Nonnull)channelId uid:(NSUInteger)uid NS_SWIFT_NAME(onPlaybackAudioFrame(beforeMixing:channelId:uid:));
@end

View File

@@ -0,0 +1,122 @@
//
// AgoraConstants.h
// AgoraRtcEngineKit
//
// Copyright (c) 2018 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
#elif TARGET_OS_MAC
#import <AppKit/AppKit.h>
#endif
/** The standard bitrate in [setVideoEncoderConfiguration]([AgoraRtcEngineKit setVideoEncoderConfiguration:]).
(Recommended) In a live broadcast, Agora recommends setting a larger bitrate to improve the video quality. When you choose AgoraVideoBitrateStandard, the bitrate value doubles in a live broadcast mode, and remains the same as in AgoraVideoProfile in a communication mode.
*/
extern NSInteger const AgoraVideoBitrateStandard;
/** The compatible bitrate in [setVideoEncoderConfiguration]([AgoraRtcEngineKit setVideoEncoderConfiguration:]).
The bitrate in both the live broadcast and communication modes remain the same as in AgoraVideoProfile.
*/
extern NSInteger const AgoraVideoBitrateCompatible;
/** The min bitrate in [setVideoEncoderConfiguration]([AgoraRtcEngineKit setVideoEncoderConfiguration:]).
The min bitrate set to default value
*/
extern NSInteger const AgoraVideoDefaultMinBitrate;
/** The min bitrate in [setVideoEncoderConfiguration]([AgoraRtcEngineKit setVideoEncoderConfiguration:]).
The min bitrate will be equal to bitrate
*/
extern NSInteger const AgoraVideoMinBitrateEqualToBitrate;
/**
* set analyze duration for real time stream
* @example "setPlayerOption(AgoraRtcMediaPlayerRealTimeStreamAnalyzeDuration,1000000)"
*/
extern NSString* const AgoraRtcMediaPlayerRealTimeStreamAnalyzeDuration;
/**
* make the player to enable audio or not
* @example "setPlayerOption(AgoraRtcMediaPlayerEnableAudio,0)"
*/
extern NSString* const AgoraRtcMediaPlayerEnableAudio;
/**
* make the player to enable video or not
* @example "setPlayerOption(AgoraRtcMediaPlayerEnableVideo,0)"
*/
extern NSString* const AgoraRtcMediaPlayerEnableVideo;
/**
* set the player enable to search metadata
* @example "setPlayerOption(AgoraRtcMediaPlayerEnableSearchMetadata,0)"
*/
extern NSString* const AgoraRtcMediaPlayerEnableSearchMetadata;
/** 120 x 120
*/
extern CGSize const AgoraVideoDimension120x120;
/** 160 x 120
*/
extern CGSize const AgoraVideoDimension160x120;
/** 180 x 180
*/
extern CGSize const AgoraVideoDimension180x180;
/** 240 x 180
*/
extern CGSize const AgoraVideoDimension240x180;
/** 320 x 180
*/
extern CGSize const AgoraVideoDimension320x180;
/** 240 x 240
*/
extern CGSize const AgoraVideoDimension240x240;
/** 320 x 240
*/
extern CGSize const AgoraVideoDimension320x240;
/** 424 x 240
*/
extern CGSize const AgoraVideoDimension424x240;
/** 360 x 360
*/
extern CGSize const AgoraVideoDimension360x360;
/** 480 x 360
*/
extern CGSize const AgoraVideoDimension480x360;
/** 640 x 360
*/
extern CGSize const AgoraVideoDimension640x360;
/** 480 x 480
*/
extern CGSize const AgoraVideoDimension480x480;
/** 640 x 480
*/
extern CGSize const AgoraVideoDimension640x480;
/** 840 x 480
*/
extern CGSize const AgoraVideoDimension840x480;
/** 960 x 540
*/
extern CGSize const AgoraVideoDimension960x540;
/** 960 x 720 (Depends on the hardware)
*/
extern CGSize const AgoraVideoDimension960x720;
/** 1280 x 720 (Depends on the hardware)
*/
extern CGSize const AgoraVideoDimension1280x720;
/** 1920 x 1080 (Depends on the hardware)
*/
extern CGSize const AgoraVideoDimension1920x1080;
/** 25400 x 1440 (Depends on the hardware)
*/
extern CGSize const AgoraVideoDimension2540x1440;
/** 3840 x 2160 (Depends on the hardware)
*/
extern CGSize const AgoraVideoDimension3840x2160;

View File

@@ -0,0 +1,38 @@
//
// AgoraRtcEngineKit.h
// AgoraRtcEngineKit
//
// Copyright (c) 2018 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "AgoraConstants.h"
#import "AgoraObjects.h"
/** Agora provides ensured quality of experience (QoE) for worldwide Internet-based voice and video communications through a virtual global network that is especially optimized for real-time web and mobile-to-mobile applications.
The AgoraRtcEngineKit class is the entry point of the Agora SDK that provides simple APIs for applications to easily start voice and video communication.
*/
@class AgoraRtcEngineKit;
@class AgoraMediaRecorder;
/**
* The event handler for direct cdn streaming
*
*/
@protocol AgoraDirectCdnStreamingEventDelegate <NSObject>
@optional
/**
* Event callback of direct cdn streaming
* @param state Current status
* @param reason Reason Code
* @param message Message
*/
- (void)onDirectCdnStreamingStateChanged:(AgoraDirectCdnStreamingState)state
reason:(AgoraDirectCdnStreamingReason)reason
message:(NSString *_Nullable)message NS_SWIFT_NAME(onDirectCdnStreamingStateChanged(_:reason:message:));
- (void)onDirectCdnStreamingStats:(AgoraDirectCdnStreamingStats *_Nonnull)stats NS_SWIFT_NAME(onDirectCdnStreamingStats(_:));
@end

View File

@@ -0,0 +1,19 @@
//
// AgoraRtcEngineKit.h
// AgoraRtcEngineKit
//
// Copyright (c) 2018 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
@class AgoraEncodedVideoFrameInfo;
@protocol AgoraEncodedVideoFrameDelegate <NSObject>
@optional
/**
* Occurs when get H264 video data interface before decoding
*/
- (BOOL)onEncodedVideoFrameReceived:(NSData * _Nonnull )videoData length:(size_t)length info:(AgoraEncodedVideoFrameInfo * _Nonnull)videoFrameInfo NS_SWIFT_NAME(onEncodedVideoFrameReceived(_:length:info:));
@end

View File

@@ -0,0 +1,77 @@
//
// Copyright (c) 2020 Agora.io. All rights reserved
// This program is confidential and proprietary to Agora.io.
// And may not be copied, reproduced, modified, disclosed to others, published
// or used, in whole or in part, without the express prior written permission
// of Agora.io.
#pragma once // NOLINT(build/header_guard)
#include "NGIAgoraExtensionControl.h"
AGORA_API agora::rtc::IExtensionControl* AGORA_CALL getAgoraExtensionControl();
AGORA_API void AGORA_CALL declareProviderVersion(
const char*, const agora::rtc::ExtensionVersion&);
typedef void(*agora_ext_entry_func_t)(void);
AGORA_API void AGORA_CALL registerProviderEntry(const char*, agora_ext_entry_func_t);
#define DECLARE_CREATE_AND_REGISTER_PROVIDER(PROVIDER_NAME, PROVIDER_CLASS, PROVIDER_INTERFACE_USED, ...) \
static void register_##PROVIDER_NAME##_to_agora() { \
auto control = getAgoraExtensionControl(); \
agora::rtc::ExtensionVersion version = \
agora::rtc::ExtensionInterfaceVersion<PROVIDER_INTERFACE_USED>::Version(); \
declareProviderVersion(#PROVIDER_NAME, version); \
if (#PROVIDER_NAME && control) { \
control->registerProvider(#PROVIDER_NAME, \
new agora::RefCountedObject<PROVIDER_CLASS>(__VA_ARGS__)); \
} \
} \
#define DECLARE_CREATE_AND_REGISTER_PROVIDER_PTR(PROVIDER_NAME, PROVIDER_INTERFACE_USED, PROVIDER_REF_PTR) \
static void register_##PROVIDER_NAME##_to_agora() { \
auto control = getAgoraExtensionControl(); \
agora::rtc::ExtensionVersion version = \
agora::rtc::ExtensionInterfaceVersion<PROVIDER_INTERFACE_USED>::Version(); \
declareProviderVersion(#PROVIDER_NAME, version); \
if (#PROVIDER_NAME && control) { \
control->registerProvider(#PROVIDER_NAME, PROVIDER_REF_PTR); \
} \
} \
#if defined (__GNUC__)
#define REGISTER_AGORA_EXTENSION_PROVIDER(PROVIDER_NAME, PROVIDER_CLASS, PROVIDER_INTERFACE_USED, ...) \
DECLARE_CREATE_AND_REGISTER_PROVIDER(PROVIDER_NAME, PROVIDER_CLASS, PROVIDER_INTERFACE_USED, __VA_ARGS__); \
__attribute__((constructor, used)) \
static void _##PROVIDER_NAME##_provider_entry() { \
registerProviderEntry(#PROVIDER_NAME, register_##PROVIDER_NAME##_to_agora); \
} \
#define REGISTER_AGORA_EXTENSION_PROVIDER_PTR(PROVIDER_NAME, PROVIDER_INTERFACE_USED, PROVIDER_REF_PTR) \
DECLARE_CREATE_AND_REGISTER_PROVIDER_PTR(PROVIDER_NAME, PROVIDER_INTERFACE_USED, PROVIDER_REF_PTR); \
__attribute__((constructor, used)) \
static void _##PROVIDER_NAME##_provider_entry() { \
registerProviderEntry(#PROVIDER_NAME, register_##PROVIDER_NAME##_to_agora); \
} \
#elif defined (_MSC_VER)
#define REGISTER_AGORA_EXTENSION_PROVIDER(PROVIDER_NAME, PROVIDER_CLASS, PROVIDER_INTERFACE_USED, ...) \
DECLARE_CREATE_AND_REGISTER_PROVIDER(PROVIDER_NAME, PROVIDER_CLASS, PROVIDER_INTERFACE_USED, __VA_ARGS__); \
static int _##PROVIDER_NAME##_provider_entry() { \
registerProviderEntry(#PROVIDER_NAME, register_##PROVIDER_NAME##_to_agora); \
return 0; \
} \
const int DUMMY_AGORA_REGEXT_##PROVIDE_NAME##_VAR = _##PROVIDER_NAME##_provider_entry(); \
#define REGISTER_AGORA_EXTENSION_PROVIDER_PTR(PROVIDER_NAME, PROVIDER_INTERFACE_USED, PROVIDER_REF_PTR) \
DECLARE_CREATE_AND_REGISTER_PROVIDER_PTR(PROVIDER_NAME, PROVIDER_INTERFACE_USED, PROVIDER_REF_PTR); \
static int _##PROVIDER_NAME##_provider_entry() { \
registerProviderEntry(#PROVIDER_NAME, register_##PROVIDER_NAME##_to_agora); \
return 0; \
} \
const int DUMMY_AGORA_REGEXT_##PROVIDE_NAME##_VAR = _##PROVIDER_NAME##_provider_entry(); \
#else
#error Unsupported Compilation Toolchain!
#endif

Some files were not shown because too many files have changed in this diff Show More