This topic describes how to implement Real-Time Streaming (RTS) using ApsaraVideo Player SDK for iOS.
Prerequisite
CocoaPods is installed in your development environment.
Integrate the SDK
Add the dependencies of ApsaraVideo Player SDK using the pod method.
Open the terminal window.
Navigate to your project directory and create a Podfile by running the following command:
pod init
Edit the Podfile to add the dependencies for the latest version of the SDK.
player_sdk_version = 'x.x.x' # We recommend using the latest version. For details, visit https://help.aliyun.com/zh/vod/developer-reference/sdk-overview-and-download?spm=a2c4g.11186623.0.0.63cde7ea3nNYgA#section-v53-2oj-xfd rts_sdk_version = '7.2.0' # The version number is independent of the Player SDK. V7.2.0 is the latest. # ApsaraVideo Player SDK pod 'AliPlayerSDK_iOS' , player_sdk_version # A bridging layer between the SDK and RTS component (AlivcArtc). Its version must be the same as the SDK version. pod 'AliPlayerSDK_iOS_ARTC' , player_sdk_version # The RTS component. pod 'RtsSDK' , rts_sdk_version
NoteFor SDK versions, see Download ApsaraVideo Player SDK. It is recommended to use V7.2.0 or later. The minimum supported version is V5.4.5.0.
Install the dependencies by running the following command:
pod install
After execution, an
*.xcworkspace
file is generated, indicating that the SDK is integrated.
Use the SDK to implement RTS
You can use the methods provided by the ApsaraVideo Player SDK to enable RTS. For additional features of the SDK, see Advanced features and API operations.
The following sections provide sample code. For details, see the open source project.
Create a player
This section explains how to play videos using the SDK. Playback can be manual or autoplay.
Create an AliPlayer instance.
setTraceID
determines which monitoring and event tracing features you can use later. For more information, see Create a player.// Create a player. self.player = [[AliPlayer alloc] init]; // We recommend that you specify the traceId. [play setTraceID:@"xxxxxx"];
NoteThe event tracking logs are uploaded to nodes in the China (Shanghai) region.
Configure listeners.
The
prepare
method must be set for manual playback, as it requires calling thestart
method in theprepare
callback to begin playback.The
onPlayerEvent
andonError
methods are crucial for handling player events and errors. We recommend that you set them up.
@interface SimplePlayerViewController ()<AVPDelegate> @end - (void)viewDidLoad { self.player = [[AliPlayer alloc] init]; self.player.playerView = self.avpPlayerView.playerView; self.player.delegate = self; //... } /** @brief Error delegate callback. @param player Pointer to the player instance. @param errorModel Error description. For details, see AliVcPlayerErrorModel. */ - (void)onError:(AliPlayer*)player errorModel:(AVPErrorModel *)errorModel { // Display the error message and implement actions such as stopping playback. } /** @brief Callback for player events. @param player Pointer to the player instance. @param eventType Event type. For details, see AVPEventType. */ -(void)onPlayerEvent:(AliPlayer*)playereventType:(AVPEventType)eventType{ switch(eventType){ caseAVPEventPrepareDone:{ // The preparation is complete. // When autoPlay is set to NO, call the start method in the prepare callback. [self.playerstart]; } break; case AVPEventAutoPlayStart: // Autoplay started. break; case AVPEventFirstRenderedStart: // First frame rendered. break; case AVPEventCompletion: // Playback completed. break; case AVPEventLoadingStart: // Buffering started. break; case AVPEventLoadingEnd: // Buffering ended. break; case AVPEventSeekEnd: // Seeking completed. break; case AVPEventLoopingStart: // Looping started. break; default: break; } } /** @brief Callback for the current playback position. @param player Pointer to the player instance. @param position The current playback position. */ - (void)onCurrentPositionUpdate:(AliPlayer*)player position:(int64_t)position { // Update the progress bar. } /** @brief Callback for buffer position. @param player Pointer to the player instance. @param position The current buffer position. */ - (void)onBufferedPositionUpdate:(AliPlayer*)player position:(int64_t)position { // Update the buffer progress. } /** @brief Callback for track information. @param player Pointer to the player instance. @param info For track information, see AVPTrackInfo. */ - (void)onTrackReady:(AliPlayer*)player info:(NSArray<AVPTrackInfo*>*)info { // Obtain multi-bitrate and track information. } /** @brief Callback for subtitle display. @param player Pointer to the player instance. @param index The index of the subtitle being displayed. @param subtitle The content of the displayed subtitle, which is a string. */ - (void)onSubtitleShow:(AliPlayer*)player index:(int)index subtitle:(NSString *)subtitle { // Display the subtitles. } /** @brief Callback for subtitle removal. @param player Pointer to the player instance. @param index The index of the subtitle being displayed. */ - (void)onSubtitleHide:(AliPlayer*)player index:(int)index { // Remove subtitles from display. } /** @brief Callback for screenshot. @param player Pointer to the player instance. @param image Screenshot image. */ - (void)onCaptureScreen:(AliPlayer *)player image:(UIImage *)image { // Preview or save the screenshot. } /** @brief Callback for switching tracks. @param player Pointer to the player instance. @param info For updated track information, see AVPTrackInfo. */ - (void)onTrackChanged:(AliPlayer*)player info:(AVPTrackInfo*)info { // The notification on bitrate switching. }
Create a data source.
ApsaraVideo Player supports four types of sources: VidSts, VidAuth, VidMps, and UrlSource. For RTS service, set the protocol to
artc://
if you use UrlSource.AVPUrlSource *urlSource = [[AVPUrlSource alloc] urlWithString:"artc://<streaming URL>"]; [self.player setUrlSource:urlSource];
Set the display view.
If the source has video content, configure the UI view to display content in the player.
self.player.playerView = self.avpPlayerView.playerView;// Set the player view.
Configure playback parameters.
ApsaraVideo Player SDK V6.3.0 and later support automatically configuring the optimal ultra-low latency. If the playback URL starts with
artc://
andMaxDelayTime
,HighBufferDuration
, orStartBufferDuration
inAVPConfig
has not been manually modified, the SDK automatically setMaxDelayTime
to 1000 ms,HighBufferDuration
to 10 ms, andStartBufferDuration
to 10 ms.If you want to customize these parameters, the following code shows how to retrieve and modify the configuration:
//1. Obtain and modify the configuration. AVPConfig *config = self.aliPlayer.getConfig; if ([playUrl hasPrefix:@"artc://"]) { // The maximum latency. Unit: milliseconds. In this example, the value is set to 1000, which indicates 1 second. [config setMaxDelayTime:1000]; // The buffer duration for playback startup. [config setStartBufferDuration:10]; // The buffer duration for stuttering recovery. [config setHighBufferDuration:10]; } else { // You can use default configuration or specify custom values. } //2. Apply the configuration. [_aliPlayer setConfig:config];
Optional.Enable autoplay, which is disabled by default.
self.player.autoPlay = YES;
Prepare for playback.
Initiate data reading and parsing by calling
[self.player prepare]
.[self.player prepare];
Start playback.
If autoplay is disabled, call the
start
method after theAVPEventPrepareDone
callback is triggered.If autoplay is enabled, you do not need to call the
start
method. The video will automatically play when data parsing is complete.
ImportantDuring autoplay, the
AVPEventPrepareDone
callback is not triggered. Instead, theAVPEventAutoPlayStart
callback occurs.[self.player start];
Control playback
ApsaraVideo Player SDK provides various controls for media playback, such as starting and pausing. Video seeking is not supported for RTS.
Start playback.
Use the start
method to start video playback.
[self.player start];
Stop playback.
Use the stop
method to terminate video playback.
[self.player stop];
For RTS, you cannot call the pause method to pause a live stream. Instead, use the stop method to stop playback and then call the prepare method to resume.
Dispose the player instance.
You can dispose the player synchronously or asynchronously.
// Synchronous disposal. The system automatically calls the stop method.
[self.player destroy];
// Asynchronous disposal. The system automatically calls the stop method.
[self.player destroyAsync];
Synchronous disposal returns the result after all player resources are released. For a faster UI response, use the asynchronous disposal method. Keep in mind:
Avoid any operations on the player object during asynchronous disposal.
There's no need to manually stop playback before calling the asynchronous disposal method, as it includes the stop process.
Use auxiliary features
Logging
// Enable logging. [AliPlayer setEnableLog:YES]; [AliPlayer setLogCallbackInfo:LOG_LEVEL_TRACE callbackBlock:nil]; // Disable logging. [AliPlayer setEnableLog:NO]; [AliPlayer setLogCallbackInfo:LOG_LEVEL_NONE callbackBlock:nil];
RTS downgrade
Automatic downgrade
If no specific streaming URL is configured for downgrade, the system automatically switches to an FLV-based streaming URL when RTS stream pulling fails.
// 1 means enabling the feature. 0 means disabling the feature. By default, it is enabled. [AliPlayerGlobalSettings setOption:ALLOW_PRE_RENDER valueInt:1];
Custom downgrade
You can specify an alternative URL, such as an HLS or FLV-based URL for downgrade. If RTS stream pulling fails, the video from the alternative URL will be played automatically.
//Set the downgrade URL. AVPUrlSource *urlSource = [[AVPUrlSource alloc] urlWithString:downgradeUrl]; //Optional. Set other parameters. AVPConfig *config = [self.player getConfig]; //Enable downgrade. [self.player enableDowngrade:urlSource config:config];
Obtain the TraceID
Each low-latency playback generates a TraceID, which can be used for troubleshooting. Retrieve the TraceID from the player event callback.
// Listen to the onPlayerEvent callback and parse the DemuxerTraceID message. - (void)onPlayerEvent:(AliPlayer*)player eventWithString:(AVPEventWithString)eventWithString description:(NSString *)description { switch (eventWithString) { case EVENT_PLAYER_DEMUXER_TRACE_ID: { NSString *traceId = description; } break; default: break; } }