多个并行的 VOD 跟踪器 vod-multiple-trackers-in-parallel
场景 scenario
在此方案中,针对两个不同的媒体以并行方式运行了两个会话,这两个会话使用两个不同的 MediaHeartbeat
实例。
此方案与不含广告的 VOD 播放方案相同,不同之处在于此方案针对两个不同的媒体以并行方式运行了两个会话。这两个会话分别使用不同的 MediaHeartbeat
实例。
除非另外指定,否则网络调用与不含广告的 VOD 播放方案相同。
参数 parameters
心跳会话
参数
值
注释
s:event:sid
唯一的会话 ID
唯一的会话 ID 一直存在于所有心跳网络调用中,直到调用
trackSessionEnd
方法。示例代码 sample-code
Android
public class MediaAnalyticsProvider implements MediaHeartbeatDelegate {
private MediaPlayer _player;
private MediaHeartbeat _heartbeat;
public MediaAnalyticsProvider(MediaPlayer player) {
if (player == null) {
throw new IllegalArgumentException("Player reference cannot be null.");
}
_player = player;
_player.addObserver(this);
// Media Heartbeat initialization
MediaHeartbeatConfig config = new MediaHeartbeatConfig();
config.trackingServer = HEARTBEAT_TRACKING_SERVER;
config.channel = HEARTBEAT_CHANNEL;
config.appVersion = HEARTBEAT_SDK;
config.ovp = HEARTBEAT_OVP;
config.playerName = PLAYER_NAME;
config.ssl = false;
config.debugLogging = true;
_heartbeat = new MediaHeartbeat(this, config);
}
@Override
public MediaObject getQoSObject() {
return MediaHeartbeat.createQoSObject(BITRATE,
STARTUP_TIME,
FPS,
DROPPED_FRAMES);
}
@Override
public Double getCurrentPlaybackTime() {
return _player.getCurrentPlaybackTime();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Bootstrap the AdobeMobile library.
Config.setContext(this.getApplicationContext());
// Create first MediaPlayer instance.
_player1 = new MediaPlayer();
// Create first MediaAnalyticsProvider instance and
// attach it to the MediaPlayer instance.
_analyticsProvider1 = new MediaAnalyticsProvider(_player1);
// Load the main media content.
Uri uri =
Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.media1);
_player1.loadContent(uri);
// Create second MediaPlayer instance.
_player2 = new MediaPlayer();
// Create second MediaAnalyticsProvider instance and
// attach it to the MediaPlayer instance.
_analyticsProvider2 = new MediaAnalyticsProvider(_player2);
// Load the main media content.
Uri uri =
Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.media2);
_player2.loadContent(uri);
}
MediaAnalyticsProvider
和 MediaHeartbeat
的实例都跟踪两个不同的会话,每个会话具有自己唯一的会话 ID。在 Charles 调试工具或调试日志中,这两个会话可以通过使用会话 ID 值进行识别。要在 Android 中显示此方案,请设置以下代码:
// Set up mediaObject
MediaObject mediaInfo = MediaHeartbeat.createMediaObject(
Configuration.MEDIA_NAME,
Configuration.MEDIA_ID,
Configuration.MEDIA_LENGTH,
MediaHeartbeat.StreamType.VOD
);
HashMap<String, String> mediaMetadata = new HashMap<String, String>();
mediaMetadata.put(CUSTOM_VAL_1, CUSTOM_KEY_1);
mediaMetadata.put(CUSTOM_VAL_2, CUSTOM_KEY_2);
// 1. Call trackSessionStart() when the user clicks Play or if autoplay is used,
// i.e., there is an intent to start playback.
_mediaHeartbeat.trackSessionStart(mediaInfo, mediaMetadata);
......
......
// 2. Call trackPlay() when the playback actually starts, i.e., when the first
// frame of main content is rendered on the screen.
_mediaHeartbeat.trackPlay();
.......
.......
// 3. Call trackComplete() when the playback reaches the end, i.e., when the
// media completes and finishes playing.
_mediaHeartbeat.trackComplete();
........
........
// 4. Call trackSessionEnd() when the playback session is over. This method must
// be called even if the user does not watch the media to completion.
_mediaHeartbeat.trackSessionEnd();
........
........
iOS
@interface MediaAnalyticsProvider : NSObject <ADBMediaHeartbeatDelegate>
@end
@implementation {
MediaPlayer *_player;
}
- (instancetype)initWithPlayer:(AVPlayer *)player {
if (self = [super init]) {
_player = player;
ADBMediaHeartbeatConfig *config =
[[ADBMediaHeartbeatConfig alloc] init];
config.trackingServer = HEARTBEAT_TRACKING_SERVER;
config.channel = HEARTBEAT_CHANNEL;
config.appVersion = HEARTBEAT_SDK_VERSION;
config.playerName = PLAYER_NAME;
config.ssl = SSL_SETTING;
config.debugLogging = DEBUG_SETTING;
ADBMediaHeartbeatConfig *config =
[[ADBMediaHeartbeatConfig alloc] init];
_mediaHeartbeat =
[[ADBMediaHeartbeat alloc] initWithDelegate:self config:config];
[self setupPlayerNotifications];
}
return self;
}
- (ADBMediaObject *)getQoSInfo {
return [ADBMediaHeartbeat createQoSObjectWithBitrate:CURRENT_BITRATE_VALUE
startupTime:CALCULATED_STARTED_TIME
fps:CALCULATED_FPS
droppedFrames:DROPPED_FRAMES_COUNT];
}
- (NSTimeInterval)getCurrentPlaybackTime {
return CMTimeGetSeconds(_player.currentTime);
}
@end
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[ADBMobile setDebugLogging:YES];
// Setup the first media player
NSURL *streamUrl = [NSURL URLWithString:CONTENT_URL_1];
if (!self.mediaPlayer1) {
self.mediaPlayer1 = [[MediaPlayer alloc] initWithContentURL:streamUrl];
//setup player
}
// Create the MediaAnalyticsProvider instance and attach it to the first
// MediaPlayer instance.
if (!self.mediaAnalyticsProvider1) {
self.mediaAnalyticsProvider1 =
[[MediaAnalyticsProvider alloc] initWithPlayerDelegate:self.mediaPlayer1];
}
// Setup the second media player
NSURL *streamUrl2 = [NSURL URLWithString:CONTENT_URL_2];
if (!self.mediaPlayer2) {
self.mediaPlayer2 = [[MediaPlayer alloc] initWithContentURL:streamUrl2];
//setup player
}
// Create the MediaAnalyticsProvider instance and attach it to the second
// MediaPlayer instance.
if (!self.mediaAnalyticsProvider2) {
self.mediaAnalyticsProvider2 =
[[MediaAnalyticsProvider alloc] initWithPlayerDelegate:self.mediaPlayer2];
}
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[ADBMobile setDebugLogging:YES];
// Setup the first media player
NSURL *streamUrl = [NSURL URLWithString:CONTENT_URL_1];
if (!self.mediaPlayer1) {
self.mediaPlayer1 = [[MediaPlayer alloc] initWithContentURL:streamUrl];
//setup player
}
// Create the MediaAnalyticsProvider instance and attach it to the first
// MediaPlayer instance.
if (!self.mediaAnalyticsProvider1) {
self.mediaAnalyticsProvider1 =
[[MediaAnalyticsProvider alloc] initWithPlayerDelegate:self.mediaPlayer1];
}
// Setup the second media player
NSURL *streamUrl2 = [NSURL URLWithString:CONTENT_URL_2];
if (!self.mediaPlayer2) {
self.mediaPlayer2 = [[MediaPlayer alloc] initWithContentURL:streamUrl2];
//setup player
}
// Create the MediaAnalyticsProvider instance and attach it to the second MediaPlayer instance.
if (!self.mediaAnalyticsProvider2) {
self.mediaAnalyticsProvider2 =
[[MediaAnalyticsProvider alloc] initWithPlayerDelegate:self.mediaPlayer2];
}
}
MediaAnalyticsProvider
和 ADBMediaHeartbeat
的实例都跟踪两个不同的会话,每个会话具有自己唯一的会话 ID。在 Charles 调试工具或调试日志中,这两个会话可以通过使用会话 ID 值进行识别。
要在 iOS 中显示此方案,请设置以下代码:
// Set up mediaObject
ADBMediaObject *mediaObject =
[ADBMediaHeartbeat createMediaObjectWithName:MEDIA_NAME
length:MEDIA_LENGTH
streamType:ADBMediaHeartbeatStreamTypeVOD];
NSMutableDictionary *mediaContextData = [[NSMutableDictionary alloc] init];
[mediaContextData setObject:CUSTOM_VAL_1 forKey:CUSTOM_KEY_1];
[mediaContextData setObject:CUSTOM_VAL_2 forKey:CUSTOM_KEY_2];
// 1. Call trackSessionStart when the user clicks Play or if autoplay is used,
// i.e., there is an intent to start playback.
[_mediaHeartbeat trackSessionStart:mediaObject data:mediaContextData];
.......
.......
// 2. Call trackPlay when the playback actually starts, i.e., when the first
// frame of the main content is rendered on the screen.
[_mediaHeartbeat trackPlay];
.......
.......
// 3. Call trackComplete when the playback reaches the end, i.e., when the
// media completes and finishes playing.
[_mediaHeartbeat trackComplete];
.......
.......
// 4. Call trackSessionEnd when the playback session is over. This method
// must be called even if the user does not watch the media to completion.
[_mediaHeartbeat trackSessionEnd];
.......
.......
JavaScript
var MediaHeartbeat = ADB.va.MediaHeartbeat;
var MediaHeartbeatConfig = ADB.va.MediaHeartbeatConfig;
var MediaHeartbeatDelegate = ADB.va.MediaHeartbeatDelegate;
function MediaAnalyticsProvider(player) {
if (!player) {
throw new Error("Illegal argument. Player reference cannot be null.")
}
this._player = player;
//Media Heartbeat initialization
var mediaConfig = new MediaHeartbeatConfig();
mediaConfig.trackingServer = Configuration.HEARTBEAT.TRACKING_SERVER;
mediaConfig.playerName = Configuration.PLAYER.NAME;
mediaConfig.channel = Configuration.HEARTBEAT.CHANNEL;
mediaConfig.debugLogging = true;
mediaConfig.appVersion = Configuration.HEARTBEAT.SDK;
mediaConfig.ssl = false;
mediaConfig.ovp = Configuration.HEARTBEAT.OVP;
var mediaDelegate = new MediaHeartbeatDelegate();
mediaDelegate.getCurrentPlaybackTime = function() {
return player.getCurrentPlaybackTime();
};
mediaDelegate.prototype.getQoSObject = function() {
return player.getQoSInfo();
};
this._mediaHeartbeat =
new MediaHeartbeat(mediaDelegate, mediaConfig, appMeasurement);
}
// Create first MediaPlayer instance.
var _player1 = new MediaPlayer();
// Create the first MediaAnalyticsProvider instance
// and attach it to the MediaPlayer instance.
analyticsProvider1 = new MediaAnalyticsProvider(_player1);
// Load the main media content.
_player1.loadContent(URL_TO_MEDIA_1);
// Create second MediaPlayer instance.
var _player2 = new MediaPlayer();
// Create second MediaAnalyticsProvider instance and
// attach it to the MediaPlayer instance.
analyticsProvider2 = new MediaAnalyticsProvider(_player2);
// Load the main media content for the 2nd player.
_player2.loadContent(URL_TO_MEDIA_2);
MediaAnalyticsProvider
和 MediaHeartbeat
的实例都跟踪两个不同的会话,每个会话具有自己唯一的会话 ID。您可以在 Charles 调试工具中看到这两个会话。
recommendation-more-help
c8eee520-cef5-4f8c-a38a-d4952cfae4eb