Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Media public api and tracker #4

Merged
merged 19 commits into from
Feb 25, 2021
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 48 additions & 9 deletions AEPMedia/Sources/Media+PublicAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,23 @@ import AEPServices
private static let LOG_TAG = "Media"

@objc(createTracker)
static func createTracker() -> MediaTracker {
//TODO
return MediaTracker()
static func createTracker() -> MediaTracker? {
return createTrackerWith(config: nil)
}

@objc(createTrackerWithConfig:)
static func createTrackerWith(config: [String: Any]?) -> MediaTracker {
//TODO
return MediaTracker()
static func createTrackerWith(config: [String: Any]?) -> MediaTracker? {
return MediaPublicTracker(dispatch: MobileCore.dispatch(event:), config: config)
}

@objc(createMediaObjectWith:id:length:streamType:mediaType:)
static func createMediaObjectWith(name: String, id: String, length: Double, streamType: String, mediaType: (String)) -> [String: Any]? {
//TODO
return [:]
static func createMediaObjectWith(name: String, id: String, length: Double, streamType: String, mediaType: MediaType) -> [String: Any]? {
guard let mediaInfo = MediaInfo(id: id, name: name, streamType: streamType, mediaType: mediaType, length: length) else {
Log.error(label: LOG_TAG, "\(#function) Error creating media Object")
return nil
}

return mediaInfo.toMap()
}

@objc(createAdBreakObjectWith:position:startTime:)
Expand Down Expand Up @@ -64,5 +66,42 @@ import AEPServices
//TODO
return [:]
}
}

@objc public enum AEPMediaEvent: Int {
case AEPMediaEventAdBreakStart
case AEPMediaEventAdBreakComplete
case AEPMediaEventAdStart
case AEPMediaEventAdComplete
case AEPMediaEventAdSkip
case AEPMediaEventChapterStart
case AEPMediaEventChapterComplete
case AEPMediaEventChapterSkip
case AEPMediaEventSeekStart
case AEPMediaEventSeekComplete
case AEPMediaEventBufferStart
case AEPMediaEventBufferComplete
case AEPMediaEventBitrateChange
case AEPMediaEventStateStart
case AEPMediaEventStateEnd

func stringValue() -> String {
switch self {
case .AEPMediaEventAdBreakStart: return MediaConstants.EventName.ADBREAK_START
case .AEPMediaEventAdBreakComplete: return MediaConstants.EventName.ADBREAK_COMPLETE
case .AEPMediaEventAdStart: return MediaConstants.EventName.AD_START
case .AEPMediaEventAdComplete: return MediaConstants.EventName.AD_COMPLETE
case .AEPMediaEventAdSkip: return MediaConstants.EventName.AD_SKIP
case .AEPMediaEventChapterStart: return MediaConstants.EventName.CHAPTER_START
case .AEPMediaEventChapterComplete: return MediaConstants.EventName.CHAPTER_COMPLETE
case .AEPMediaEventChapterSkip: return MediaConstants.EventName.CHAPTER_SKIP
case .AEPMediaEventSeekStart: return MediaConstants.EventName.SEEK_START
case .AEPMediaEventSeekComplete: return MediaConstants.EventName.SEEK_COMPLETE
case .AEPMediaEventBufferStart: return MediaConstants.EventName.BUFFER_START
case .AEPMediaEventBufferComplete: return MediaConstants.EventName.BUFFER_COMPLETE
case .AEPMediaEventBitrateChange: return MediaConstants.EventName.BITRATE_CHANGE
case .AEPMediaEventStateStart: return MediaConstants.EventName.STATE_START
case .AEPMediaEventStateEnd: return MediaConstants.EventName.STATE_END
}
}
}
21 changes: 21 additions & 0 deletions AEPMedia/Sources/MediaConstants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ enum MediaConstants {
static let ANALYTICS_VISITOR_ID = "aid"
}

enum Media {
static let EVENT_TYPE = "com.adobe.eventtype.media"
static let EVENT_SOURCE_TRACKER_REQUEST = "com.adobe.eventsource.media.requesttracker"
static let EVENT_SOURCE_TRACKER_RESPONSE = "com.adobe.eventsource.media.responsetracker"
static let EVENT_SOURCE_TRACK_MEDIA = "com.adobe.eventsource.media.trackmedia"
static let EVENT_NAME_CREATE_TRACKER = "Media::CreateTrackerRequest"
static let EVENT_NAME_TRACK_MEDIA = "Media::TrackMedia"
}

enum EventName {
static let SESSION_START = "sessionstart"
static let SESSION_END = "sessionend"
Expand Down Expand Up @@ -154,4 +163,16 @@ enum MediaConstants {
static let SITE_ID = "a.media.ad.site"
static let CREATIVE_URL = "a.media.ad.creativeURL"
}

enum Tracker {
static let ID = "trackerid"
static let SESSION_ID = "sessionid"
static let CREATED = "trackercreated"
static let EVENT_NAME = "event.name"
static let EVENT_PARAM = "event.param"
static let EVENT_METADATA = "event.metadata"
static let EVENT_TIMESTAMP = "event.timestamp"
static let EVENT_INTERNAL = "event.internal"
static let PLAYHEAD = "time.playhead"
}
}
148 changes: 148 additions & 0 deletions AEPMedia/Sources/MediaObject.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
Copyright 2021 Adobe. All rights reserved.
This file is licensed to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.
*/

import AEPServices

class MediaInfo: Equatable {
static let LOG_TAG = "MediaInfo"
static let DEFAULT_PREROLL_WAITING_TIME_IN_MS: Double = 250.0 //250 milliseconds
let id: String
let name: String
let streamType: String
let mediaType: MediaType
let length: Double
let resumed: Bool
let prerollWaitingTime: Double
let granularAdTracking: Bool

static func == (lhs: MediaInfo, rhs: MediaInfo) -> Bool {
return lhs.id == rhs.id &&
lhs.name == rhs.name &&
lhs.streamType == rhs.streamType &&
lhs.mediaType == rhs.mediaType &&
lhs.length == rhs.length &&
lhs.resumed == rhs.resumed &&
lhs.prerollWaitingTime == rhs.prerollWaitingTime &&
lhs.granularAdTracking == rhs.granularAdTracking
}

init?(id: String, name: String, streamType: String, mediaType: MediaType, length: Double, resumed: Bool = false, prerollWaitingTime: TimeInterval = DEFAULT_PREROLL_WAITING_TIME_IN_MS, granularAdTracking: Bool = false) {

guard !id.isEmpty else {
Log.debug(label: Self.LOG_TAG, "\(#function) - Error creating MediaInfo, id must not be Empty")
return nil
}

guard !name.isEmpty else {
Log.debug(label: Self.LOG_TAG, "\(#function) - Error creating MediaInfo, name must not be Empty")
return nil
}

guard !streamType.isEmpty else {
Log.debug(label: Self.LOG_TAG, "\(#function) - Error creating MediaInfo, stream type must not be Empty")
return nil
}

guard length > 0 else {
Log.debug(label: Self.LOG_TAG, "\(#function) - Error creating MediaInfo, length must not be less than zero")
return nil
}

self.id = id
self.name = name
self.streamType = streamType
self.mediaType = mediaType
self.length = length
self.resumed = resumed
self.prerollWaitingTime = prerollWaitingTime
self.granularAdTracking = granularAdTracking
}

convenience init?(info: [String: Any]?) {
guard info != nil else {
return nil
}

guard let id = info?[MediaConstants.MediaInfo.ID] as? String else {
Log.debug(label: Self.LOG_TAG, "\(#function) - Error parsing MediaInfo, invalid id")
return nil
}

guard let name = info?[MediaConstants.MediaInfo.NAME] as? String else {
Log.debug(label: Self.LOG_TAG, "\(#function) - Error parsing MediaInfo, invalid name")
return nil
}

guard let streamType = info?[MediaConstants.MediaInfo.STREAM_TYPE] as? String else {
Log.debug(label: Self.LOG_TAG, "\(#function) - Error parsing MediaInfo, invalid stream type. Sample values -> {\"VOD\", \"LIVE\" ...}")
return nil
}

guard let mediaTypeString = info?[MediaConstants.MediaInfo.MEDIA_TYPE] as? String else {
Log.debug(label: Self.LOG_TAG, "\(#function) - Error parsing MediaInfo, invalid media type. Valid values -> {\"video\", \"audio\"}")
return nil
}

guard let mediaType: MediaType = MediaType(rawValue: mediaTypeString) else {
Log.debug(label: Self.LOG_TAG, "\(#function) - Error parsing MediaInfo, invalid media type")
return nil
}

guard let length = info?[MediaConstants.MediaInfo.LENGTH] as? Double else {
Log.debug(label: Self.LOG_TAG, "\(#function) - Error parsing MediaInfo, invalid length")
return nil
}

let resumed = info?[MediaConstants.MediaInfo.RESUMED] as? Bool ?? false

let prerollWaitTimeVal: Double = info?[MediaConstants.MediaInfo.PREROLL_TRACKING_WAITING_TIME] as? Double ?? Self.DEFAULT_PREROLL_WAITING_TIME_IN_MS

let prerollWaitingTime: TimeInterval = TimeInterval(prerollWaitTimeVal)

let granularAdTracking = info?[MediaConstants.MediaInfo.GRANULAR_AD_TRACKING] as? Bool ?? false

self.init(id: id, name: name, streamType: streamType, mediaType: mediaType, length: length, resumed: resumed, prerollWaitingTime: prerollWaitingTime, granularAdTracking: granularAdTracking)
}

func toMap() -> [String: Any] {
var mediaInfoMap: [String: Any] = [:]
mediaInfoMap[MediaConstants.MediaInfo.ID] = self.id
mediaInfoMap[MediaConstants.MediaInfo.NAME] = self.name
mediaInfoMap[MediaConstants.MediaInfo.LENGTH] = self.length
mediaInfoMap[MediaConstants.MediaInfo.STREAM_TYPE] = self.streamType
mediaInfoMap[MediaConstants.MediaInfo.MEDIA_TYPE] = self.mediaType.rawValue
mediaInfoMap[MediaConstants.MediaInfo.RESUMED] = self.resumed
mediaInfoMap[MediaConstants.MediaInfo.PREROLL_TRACKING_WAITING_TIME] = self.prerollWaitingTime
mediaInfoMap[MediaConstants.MediaInfo.GRANULAR_AD_TRACKING] = self.granularAdTracking

return mediaInfoMap
}
}

class AdBreakInfo {

}

class AdInfo {

}

class ChapterInfo {

}

class QoEInfo {

}

class StateInfo {

}
Loading