Skip to main content

V2.5.100 Media Center Tutorial

1. Overview

The new Media Center supports multi-stream playback, playback initialization, aircraft pre-recording, real-time stream information retrieval, and multiple streaming channels.

Note: Changes in Media Center from version 2.5.2 to 2.5.100

  • Added multi-stream publishing functionality
  • Package name changed from com.autel.module_player to com.autel.player
  • Added multi-stream publishing functionality, RTMP streaming now implemented through RTMPPublisherNew while maintaining compatibility with old interfaces
  • Optimized some interface callbacks, such as IPublishListener

2. New Media Center API Description

2.1 Multi-stream Player

2.1.1 Multi-stream Player Description

Supports simultaneous playback of multiple streams (infrared, visible light, etc.) and playback initialization.

2.1.2 Multi-stream Player API Description

Uses the singleton instance of AutelPlayerManager class and instances of AutelPlayer and AutelPlayerView classes to call interfaces.

  • AutelPlayerManager.java Interface Description
import com.autel.player.player.AutelPlayerManager
import com.autel.player.player.autelplayer.AutelPlayer

/**
* Singleton instance of AutelPlayerManager
*/
public synchronized static AutelPlayerManager getInstance()

/**
* Add AutelPlayer instance to mAutelPlayerList
*
* @param player The AutelPlayer instance to add
*/
public void addAutelPlayer(AutelPlayer player)

/**
* Add MediaCodec listener
* @param key Key value
* @param callbackWith Callback interface OnRenderFrameInfoListener
*/
public void addCodecListeners(String key, final OnRenderFrameInfoListener callbackWith)
  • AutelPlayer.java Interface Description
import com.autel.player.player.autelplayer.AutelPlayer
/**
* Constructor
* @param channelId: Channel ID as defined in SDKConstants
*/
public AutelPlayer(int channelId)

/**
* Add view for video
* @param view AutelPlayerView object for displaying video
*/
public void addVideoView(AutelPlayerView view)

/**
* Remove video view
*/
public void removeVideoView()

/**
* Set video stream listener
* @param ls Listener object implementing IVideoStreamListener interface
*/
public void setVideoInfoListener(IVideoStreamListener ls)
  • AutelPlayerView.java Interface Description
/**
* Create a new AutelPlayerView
*
* @param context Context associated with this view
*/
public AutelPlayerView(Context context)

/**
* Create a new AutelPlayerView
*
* @param context Context associated with this view
* @param attrs Attributes from XML tag that fills this view
*/
public AutelPlayerView(Context context, AttributeSet attrs)

2.1.3 Multi-stream Player Interface Usage Example

// Initialize player manager singleton
SDKManager.get().init(applicationContext, true)

// Create player TextureView
private fun createAutelCodecView(): AutelPlayerView? {
val codecView = AutelPlayerView(activity)
val params = LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT
)
codecView.layoutParams = params
return codecView
}

val codecView = createAutelCodecView()
uiBinding.root.addView(codecView, 0)

// Create AutelPlayer
mAutelPlayer = AutelPlayerManager.getInstance().getAutelPlayer(SDKConstants.STREAM_CHANNEL_16110);

// Pass TextureView to player
mAutelPlayer?.addVideoView(codecView)

// Set stream info callback interface
mAutelPlayer?.setVideoInfoListener(object : IVideoStreamListener {
override fun onVideoSizeChanged(playerId: Int, width: Int, height: Int) {
isFrameSaved = false;
}

override fun onVideoInfoCallback(playerId: Int, x: Int, y: Int, w: Int, h: Int) {
}

override fun onFrameYuv(yuv: ByteBuffer?, mediaInfo: MediaInfo?) {
Log.i("MuiltCodecFragment", " yuv ${yuv?.capacity()} mediaInfo ${mediaInfo.toString()}")
if (!isFrameSaved && yuv != null && mediaInfo != null){
isFrameSaved = true;
if (mediaInfo.pixelFormat == MediaInfo.PixelFormat.PIX_FMT_NV12){
saveYuvToFile(yuv, mediaInfo.width, mediaInfo.height, mediaInfo.stride, mediaInfo.sliceHeight)
}
}
}

override fun onVideoErrorCallback(playerId: Int, type: Int, errorContent: String?) {
}

override fun onStreamSourceChanged(playerId: Int, newType: StreamData.StreamSourceType) {
}
})

2.2 Live Streaming

2.2.1 Start RTMP Streaming

import com.autel.publisher.IPublishListener

private var mPublisher = RTMPPublisherNew()
var iCurrentPort: Int = SDKConstants.STREAM_CHANNEL_16110
private var rtmpUrl: String = "rtmp://116.205.231.28/live/livestream/zoom77"

var param = PublishParam.Builder().setUrl(rtmpUrl).setStreamSource(iCurrentPort).build()
mPublisher.configure(param)

mPublisher.setOnPublishListener(object : IPublishListener {
override fun onConnecting() {
SDKLog.d(TAG, "Rtmp Status : connecting")
connectStatus = 0;
}

override fun onConnected() {
SDKLog.d(TAG, "Rtmp Status : connected.")
connectStatus = 1;
}

override fun onConnectedFailed(code: PublishErrorCode) {
SDKLog.d(TAG, "Rtmp Status : connected failed code=" + code)
connectStatus = 2;
}

override fun onStartPublish() {
SDKLog.d(TAG, "Rtmp Status : start publish stream")
}

override fun onStopPublish() {
SDKLog.d(TAG, "Rtmp Status : stoppublish now")
}

override fun onFpsStatistic(fps: Int, channelName: String) {
SDKLog.d(TAG, "Rtmp upload fps : " + fps)
}

override fun onVideoBitrate(value: Int, channelName: String) {
SDKLog.d(TAG, "Rtmp onVideoBriate : " + value + " KBPS")
}

override fun onAudioBitrate(value: Int) {
SDKLog.d(TAG, "Rtmp onAudioBriate : " + value + " KBPS")
}

override fun onPublishSuccess() {
SDKLog.d(TAG, "Rtmp onPublishSuccess")
}

override fun onPublishFailed(errorCode: PublishErrorCode) {
SDKLog.d(TAG, "Rtmp onPublishFailed errcode" + errorCode)
}

override fun onPublishFailed(channelName: String, errorCode: PublishErrorCode) {
SDKLog.d(TAG, "Rtmp onPublishFailed errcode" + errorCode)
}

override fun onReconnect() {
SDKLog.d(TAG, "Rtmp onReconnect")
}
})

mPublisher.start()

2.2.2 Stop RTMP Streaming

mPublisher.stop()

2.2.3 Switch RTMP Streaming Camera

if(iCurrentPort == SDKConstants.STREAM_CHANNEL_16110){
iCurrentPort = SDKConstants.STREAM_CHANNEL_16115
mPublisher.switchStreamSource(iCurrentPort, true)
} else {
iCurrentPort = SDKConstants.STREAM_CHANNEL_16110
mPublisher.switchStreamSource(iCurrentPort, true)
}

2.3 Aircraft Pre-recording

2.3.1 Aircraft Pre-recording Description

When aircraft pre-recording is enabled, it records approximately 30 seconds of content and saves it as a fixed-name file, overwriting the previously saved file. This ensures that the most recent 30 seconds of video content is always preserved. If the aircraft loses connection, this video content can be used to help locate the aircraft.

2.3.2 Aircraft Pre-recording API Description

The following APIs are available through the AutelPlayerManager singleton instance for aircraft pre-recording.

/**
* Enable recording for the corresponding video type (visible light, night vision, infrared) for up to 30 seconds
* Returns true: start successful, false: start failed (invalid parameters)
* @param videoType: the video type
* @param cacheDuration: use ms
*/
public boolean openVideoCache(VideoType videoType, long cacheDuration)

/**
* Disable recording for the corresponding video type (visible light, night vision)
* Returns true: close successful, false: close failed (invalid parameters)
* @param videoType the video type
*/
public boolean closeVideoCache(VideoType videoType)

/**
* Set the path for saving recorded videos, defaults to root directory if not set
* @param path the video path
*/
public void setCachePath(String path)

/**
* Check if recording is enabled for the corresponding video type (visible light, night vision)
*/
public boolean isOpenVideoCache(VideoType videoType)

2.3.4 Aircraft Pre-recording Interface Usage Example

// Enable 30s time-lapse function
AutelPlayerManager.getInstance().openVideoCache(VideoType.VISIBLE_LIGHT, 30_000)

// Disable 30s time-lapse function
AutelPlayerManager.getInstance().closeVideoCache(VideoType.VISIBLE_LIGHT)

// Set path for saving recorded videos, defaults to root directory if not set
AutelPlayerManager.getInstance().setCachePath(AutelDirPathUtils.getLookFlightVideoCachePath())

// Check if 30s time-lapse function is enabled for the corresponding video type
AutelPlayerManager.getInstance().isOpenVideoCache(VideoType.VISIBLE_LIGHT)

2.4 Get Real-time Stream Information

2.4.1 Real-time Stream Information Description

Can obtain real-time stream information for debugging and problem location.

2.4.2 Real-time Stream Information API Description

The following APIs are available through AutelPlayer instance:

// Decoding frame rate
public int getVideoFps()

// Receiving frame rate
public int getRecvFps()

// Refresh frame rate
public int getRenderFps()

// Received bit rate
public int getRecvBitrate()

// Number of key frames received in 60 seconds
public int getKeyFrameNum()

// Number of key frame requests in 60 seconds
public int getKeyFrameReqNum()

// Packet loss count in 1 second
public int getPktLossNum()

// Video width
public int getVideoWidth()

// Video height
public int getVideoHeigh()