logo
On this page

Media Player

2024-07-27

Feature Overview

The media player component provides the ability to play audio and video media files, and also supports pushing the audio and video data of the played media files to the stream.

Application Scenarios

  • Playing test audio: You can use the media player to play test audio and verify whether the audio playback device is working properly.
  • Playing background music: Use the media player to play music and mix it into the stream so that remote users can hear the background music.
  • Playing video files: Combine with custom video capture functionality to push the video data of media resources to the stream, so remote users can play and watch it.

Supported Formats

The media player supports the following formats and protocols by default:

Video Codec Formats:

  • H263, H264, H265, MPEG4, MJPEG

Audio Codec Formats:

  • AAC, MP2, MP3, FLAC, WMA V1, WMA V2, PCM, AC3, EAC3

Container Formats:

  • WAV, FLAC, MP3, MP4, MOV, MPEG-TS, FLV, Matroska (MKV), AVI, ASF, JPEG

Supported Protocols:

  • HTTP, HTTPS, HLS
Note

If you need support for other formats, please contact ZEGOCLOUD Technical Support.

Sample Source Code Download

Please refer to Download Sample Source Code to get the source code.

For related source code, please check the files in the "/ZegoExpressExample/Examples/Others/MediaPlayer" directory.

Prerequisites

Before implementing the media player feature, please ensure:

Usage Steps

1 Create media player

Call the createMediaPlayer interface of "ZegoExpressEngine" to create a media player instance. One media player instance can only play one audio or video file. The engine supports creating up to 10 player instances at the same time to achieve the effect of playing multiple media resources simultaneously. If 10 player instances already exist, calling the create player interface again will return nil.

  • Call example

    ZegoMediaPlayer *mediaPlayer = [[ZegoExpressEngine sharedEngine] createMediaPlayer];
    
    if (mediaPlayer) {
        self.mediaPlayer = mediaPlayer;
    } else {
        NSLog(@"Failed to create player");
    }

2 (Optional) Set event callback for player

Call the setEventHandler interface of the media player to set event callbacks for the player to receive notifications such as "player playback status change", "player network status update", "player playback progress change", etc.

  • Call example

    // Here self implements the `ZegoMediaPlayerEventHandler` protocol
    [self.mediaPlayer setEventHandler:self];
    // Player playback status callback
    
    // @param mediaPlayer Player instance callback
    // @param state Player status
    // @param errorCode Error code, for details please refer to the common error codes document
    - (void)mediaPlayer:(ZegoMediaPlayer *)mediaPlayer stateUpdate:(ZegoMediaPlayerState)state errorCode:(int)errorCode {
        switch (state) {
            case ZegoMediaPlayerStateNoPlay:
                // Playback stopped status
                break;
            case ZegoMediaPlayerStatePlaying:
                // Playing status
                break;
            case ZegoMediaPlayerStatePausing:
                // Paused status
                break;
            case ZegoMediaPlayerStatePlayEnded:
                // Current track playback completed, operations such as playing the next track can be performed
                break;
        }
    }
    
    // Player network status callback
    
    // @param mediaPlayer Player instance callback
    // @param networkEvent Network status event
    - (void)mediaPlayer:(ZegoMediaPlayer *)mediaPlayer networkEvent:(ZegoMediaPlayerNetworkEvent)networkEvent {
        if (networkEvent == ZegoMediaPlayerNetworkEventBufferBegin) {
            // Show Loading UI
        } else if (networkEvent == ZegoMediaPlayerNetworkEventBufferEnded) {
            // Hide Loading UI
        }
    }
    
    // Player playback progress callback
    
    // @param mediaPlayer Player instance callback
    // @param millisecond Progress, unit is milliseconds
    - (void)mediaPlayer:(ZegoMediaPlayer *)mediaPlayer playingProgress:(unsigned long long)millisecond {
        // Update progress bar
    }

3 Load media resources

Call the media player's loadResource to specify the media resource to be played, which can be an absolute path to a local resource or a URL to a network resource, such as http://your.domain.com/your-movie.mp4. Users can obtain the result of loading the file by passing in callback parameters.

  • Call example

    // This example gets the absolute path of the sample.mp4 file in the App bundle
    NSString *fileURL = [[NSBundle mainBundle] pathForResource:@"sample" ofType:@"mp4"];
    
     // Load resource, can pass absolute path of local resource or URL of network resource
    [self.mediaPlayer loadResource:fileURL callback:^(int errorCode) {
        // Can perform logic such as updating UI
        if (errorCode == 0) {
             // File loaded successfully, now you can start playing media resources
             // [self.mediaPlayer start];
        }
    }];

If users need to load binary audio data, they can call the media player's loadResourceFromMediaData to specify the binary audio data to be played. Users can obtain the result of loading the data by passing in callback parameters.

  • Call example

     //Load resource, pass in the binary audio data to be loaded and the starting position
    [self.mediaPlayer loadResourceFromMediaData:data startPosition:0L callback:^(int errorCode) {
        // Can perform logic such as updating UI
        if (errorCode == 0) {
             // File loaded successfully, now you can start playing media resources
            // [self.mediaPlayer start];
        }
    }];
Warning

If the media resource has already been loadResource or is currently playing, please call the stop interface first to stop playback, then call the loadResource interface to load new media resources, otherwise the loading will fail.

4 Playback control

Playback status control

After successfully calling loadResource to load the file, you can call start, pause, resume, stop to start and stop playback. Once the player's internal state changes, the stateUpdate callback of ZegoMediaPlayer will be triggered.

Users can also call currentState at any time to get the current status of the player.

If enableRepeat is set to "YES", the player will automatically replay after finishing playing the file.

// Set whether to repeat playback
[self.mediaPlayer enableRepeat:YES];
// Start playing, need to call interface to load media file before playing
[self.mediaPlayer start];
// Pause
[self.mediaPlayer pause];
// Resume
[self.mediaPlayer resume];
// Stop
[self.mediaPlayer stop];

Playback status transition diagram:

Playback progress control

The progress of playing the file will be called back through the mediaPlayer

method. The default interval for triggering callbacks is 1000 ms, which can be changed by setProgressInterval.

Users can also get the current playback progress through currentProgress.

Playback progress can be adjusted through the seekTo interface.

  • Call example

    // Set playback progress callback interval to 1000ms, that is, every 1000 ms will receive one - (void)mediaPlayer:(ZegoMediaPlayer *)mediaPlayer playingProgress:(unsigned long long)millisecond callback
    [self.mediaPlayer setProgressInterval:1000];
    
    // Get the total duration of the currently playing media file, unit is milliseconds
    unsigned long long totalDuration = self.mediaPlayer.totalDuration;
    
    // Get the playback progress of the player, unit is milliseconds
    unsigned long long progress = self.mediaPlayer.currentProgress;
    
    NSLog(@"process: %llu", progress);
    
    // Seek to half of the total duration, progress unit is milliseconds
    [self.mediaPlayer seekTo:totalDuration/2 callback:^(int errorCode) {
        NSLog(@"errorCode: %d", errorCode);
    }];

Playback speed control

After loading resources is completed, users can set the current playback speed through setPlaySpeed.

  • Call example

    // Set the playback speed of the player, must be called after loading resources is completed
    // Set 2x speed playback, playback speed range is 0.3 ~ 4.0, default is 1.0
    [self.mediaPlayer setPlaySpeed:2.0];

Player audio control

Get and control playback volume through playVolume and setPlayVolume.

Get and control publish stream volume through publishVolume and setPublishVolume.

Call enableAux to mix the sound of the file into the stream being published.

Note

If you want to use the mixing capability, you must set microphone permissions. If you do not want to record microphone sound, you can mute the microphone through muteMicrophone.

Call muteLocal to make local playback silent but still be able to mix sound into the stream normally.

// Get the current playback volume of the player
int playVolume = self.mediaPlayer.playVolume;

// Set player volume to half of original
[self.mediaPlayer setPlayVolume:playVolume/2];

// Get the current publish stream volume of the player
int publishVolume = [self.mediaPlayer publishVolume];

// Set player publish stream volume
[self.mediaPlayer setPublishVolume:publishVolume];

// Enable mixing the sound of the resource into the stream being published
[self.mediaPlayer enableAux:YES];

// Enable local silent playback
[self.mediaPlayer muteLocal:YES];

If you want to get the audio data of the file, you can set the audio frame callback through setAudioHandler.

  • Call example

    // Here self implements the `ZegoMediaPlayerAudioHandler` protocol and calls the set interface of the player
    [self.mediaPlayer setAudioHandler:self];
    // Player audio frame data callback
    // @param mediaPlayer Player instance callback
    // @param data Raw data of audio frame
    // @param dataLength Length of data
    // @param param Audio frame parameters
    - (void)mediaPlayer:(ZegoMediaPlayer *)mediaPlayer audioFrameData:(const unsigned char *)data dataLength:(unsigned int)dataLength param:(ZegoAudioFrameParam *)param {
    // Received media player audio data callback
    }

Player video control

When playing video resources, use setPlayerCanvas to set the display view of the video.

  • Call example

    // Set playback view
    [self.mediaPlayer setPlayerCanvas:[ZegoCanvas canvasWithView:self.mediaPlayerView]];

If you want to get the video data of the file, you can set the video frame callback through setVideoHandler.

  • Interface prototype

    // Set player video data callback, video frame data format and data type you want to receive
    - (void)setVideoHandler:(nullable id<ZegoMediaPlayerVideoHandler>)handler format:(ZegoVideoFrameFormat)format type:(ZegoVideoBufferType)type;
    @protocol ZegoMediaPlayerVideoHandler <NSObject>
    
    @optional
    
    // Player video frame raw data callback
    // @param mediaPlayer Player instance callback
    // @param data Raw data of video frame (e.g.: RGBA only needs to consider data[0], I420 needs to consider data[0,1,2])
    // @param dataLength Length of data (e.g.: RGBA only needs to consider dataLength[0], I420 needs to consider dataLength[0,1,2])
    // @param param Video frame parameters
    - (void)mediaPlayer:(ZegoMediaPlayer *)mediaPlayer videoFrameRawData:(const unsigned char * _Nonnull * _Nonnull)data dataLength:(unsigned int *)dataLength param:(ZegoVideoFrameParam *)param;
    
    // Player video frame CVPixerBuffer data callback
    // @param mediaPlayer Player instance callback
    // @param buffer Video frame data encapsulated as CVPixerBuffer
    // @param param Video frame parameters
    - (void)mediaPlayer:(ZegoMediaPlayer *)mediaPlayer videoFramePixelBuffer:(CVPixelBufferRef)buffer param:(ZegoVideoFrameParam *)param;
    
    @end
  • Call example

    // Set video data format to NV12, data type to CVPixelBuffer
    [self.mediaPlayer setVideoHandler:self format:ZegoVideoFrameFormatNV12 type:ZegoVideoBufferTypeCVPixelBuffer];
    // Player video frame CVPixerBuffer data callback
    // @param mediaPlayer Player instance callback
    // @param buffer Video frame data encapsulated as CVPixerBuffer
    // @param param Video frame parameters
    - (void)mediaPlayer:(ZegoMediaPlayer *)mediaPlayer videoFramePixelBuffer:(CVPixelBufferRef)buffer param:(ZegoVideoFrameParam *)param {
    // NSLog(@"pixel buffer video frame callback. format:%d, width:%f, height:%f", (int)param.format, param.size.width, param.size.height);
    }
Warning

When the data type "type" is set to "ZegoVideoBufferTypeCVPixelBuffer", the data format "format" only supports setting to "ZegoVideoFrameFormatI420", "ZegoVideoFrameFormatNV12", "ZegoVideoFrameFormatBGRA32", "ZegoVideoFrameFormatARGB32"; setting to other unsupported formats will not callback video frame data in the future.

Publish stream the video played by the player

  1. Before publishing the player's video stream, you need to first set up video frame callback listening through setVideoHandler to get the video frame data thrown by videoFrameRawData or videoFramePixelBuffer.

  2. Use custom method to capture video and mix the obtained video data into the stream publishing data. For detailed operations, please refer to Custom Video Capture.

Note

When capturing custom data, it is recommended that developers define a "flag" marker:

  • When the onStart callback is triggered, set the "flag" marker to "True", indicating that you can start sending custom captured video data to the SDK.
  • When the onStop callback is triggered, set the "flag" marker to "False", indicating that you need to stop sending captured video data to the SDK.
  1. Developers need to add judgment logic for "flag" in videoFrameRawData or videoFramePixelBuffer. When "flag" is set to "True" (that is, when the onStart callback is triggered), call the sendCustomVideoCapturePixelBuffer method to send the obtained video data to the SDK.

  2. Call startPublishingStream to start publishing stream. Please refer to "Stream Publishing" in Quick Start - Implementation Flow.

Voice Changer

To handle scenarios such as changing the pitch of accompaniment in KTV, you can call the media player's enableVoiceChanger interface to implement voice changer functionality. Developers can set the voice changer effect through the pitch parameter "pitch" in the ZegoVoiceChangerParam object. The value range of this parameter is [-12.0, 12.0]. The larger the value, the sharper the sound. Voice changer is disabled by default.

ZegoVoiceChangerParam *param = [[ZegoVoiceChangerParam alloc] init];
// Male voice to child voice
param.pitch = 8.0f;
//Male voice to female voice
param.pitch = 4.0f;
// Female voice to child voice
param.pitch = 6.0f;
// Female voice to male voice
param.pitch = -3.0f;
[self.mediaPlayer enableVoiceChanger:YES param:param audioChannel:ZegoMediaPlayerAudioChannelAll];

5 Destroy media player

After using the player, you need to set the player instance variable to nil in time to destroy the media player and release occupied resources. Call example:

self.mediaPlayer = nil;
Note

When the reference count of the media player instance object is 0, the player instance will be destroyed and its occupied resources will be released.

FAQ

  1. How to switch playback resources during playback?

First call the player's stop interface, then call the loadResource interface again to load new resources.

Previous

Direct to CDN

Next

Audio Effect Player