266 lines
7.9 KiB
Swift
266 lines
7.9 KiB
Swift
//
|
|
// FlutterMediaLoadRequestDataHelper.swift
|
|
// flutter_cast_framework
|
|
//
|
|
// Created by Gianluca Paradiso on 19/11/21.
|
|
//
|
|
|
|
import Foundation
|
|
import GoogleCast
|
|
|
|
func getFlutterMediaStatus(mediaStatus: GCKMediaStatus?) -> MediaStatus {
|
|
let result = MediaStatus()
|
|
|
|
if (mediaStatus == nil) {
|
|
return result
|
|
}
|
|
|
|
result.isPlayingAd = NSNumber(value: mediaStatus?.playingAd ?? false)
|
|
result.mediaInfo = getFlutterMediaInfo(mediaInfo: mediaStatus?.mediaInformation)
|
|
result.playerState = getFlutterPlayerState(playerState: mediaStatus?.playerState)
|
|
result.adBreakStatus = getFlutterAdBreakStatus(adBreakStatus: mediaStatus?.adBreakStatus)
|
|
|
|
return result
|
|
}
|
|
|
|
func getFlutterAdBreakStatus(adBreakStatus: GCKAdBreakStatus?) -> AdBreakStatus {
|
|
let result = AdBreakStatus()
|
|
|
|
if (adBreakStatus == nil) {
|
|
return result
|
|
}
|
|
|
|
result.adBreakId = adBreakStatus?.adBreakID
|
|
result.adBreakClipId = adBreakStatus?.adBreakClipID
|
|
result.whenSkippableMs = getFlutterWhenSkippableMs(whenSkippable: adBreakStatus?.whenSkippable)
|
|
|
|
return result
|
|
}
|
|
|
|
func getFlutterWhenSkippableMs(whenSkippable: TimeInterval?) -> NSNumber {
|
|
if (whenSkippable == nil || whenSkippable?.isNaN == true || whenSkippable?.isInfinite == true) {
|
|
return 0
|
|
}
|
|
|
|
let whenSkippableSecs = whenSkippable ?? 0
|
|
let whenSkippableMs = Int(whenSkippableSecs * 1000)
|
|
|
|
return NSNumber(value: whenSkippableMs)
|
|
}
|
|
|
|
func getFlutterPlayerState(playerState: GCKMediaPlayerState?) -> PlayerState {
|
|
switch playerState {
|
|
case .unknown:
|
|
return PlayerState.unknown
|
|
case .idle:
|
|
return PlayerState.idle
|
|
case .playing:
|
|
return PlayerState.playing
|
|
case .paused:
|
|
return PlayerState.paused
|
|
case .buffering:
|
|
return PlayerState.buffering
|
|
case .loading:
|
|
return PlayerState.loading
|
|
default:
|
|
return PlayerState.unknown
|
|
}
|
|
}
|
|
|
|
func getFlutterMediaInfo(mediaInfo: GCKMediaInformation?) -> MediaInfo {
|
|
let result = MediaInfo()
|
|
|
|
if (mediaInfo == nil) {
|
|
return result
|
|
}
|
|
|
|
result.contentId = mediaInfo?.contentID
|
|
result.contentType = mediaInfo?.contentType
|
|
result.customDataAsJson = "\(mediaInfo?.customData ?? {})"
|
|
result.mediaMetadata = getFlutterMediaMetadata(mediaMetadata: mediaInfo?.metadata)
|
|
result.mediaTracks = getFlutterMediaTracks(mediaTracks: mediaInfo?.mediaTracks)
|
|
result.streamDuration = getStreamDuration(streamDuration: mediaInfo?.streamDuration)
|
|
result.streamType = getFlutterStreamType(streamType: mediaInfo?.streamType)
|
|
result.adBreakClips = getFlutterAdBreakClips(adBreakClips: mediaInfo?.adBreakClips)
|
|
|
|
return result
|
|
}
|
|
|
|
func getStreamDuration(streamDuration: TimeInterval?) -> NSNumber {
|
|
if (streamDuration == nil || streamDuration?.isNaN == true || streamDuration?.isInfinite == true) {
|
|
return 0
|
|
}
|
|
|
|
let durationRounded = streamDuration?.rounded() ?? 0
|
|
let durationInt = Int(durationRounded)
|
|
return NSNumber(value: durationInt)
|
|
}
|
|
|
|
func getFlutterStreamType(streamType: GCKMediaStreamType?) -> StreamType {
|
|
switch streamType {
|
|
case .buffered:
|
|
return StreamType.buffered
|
|
case .live:
|
|
return StreamType.live
|
|
case .unknown:
|
|
return StreamType.invalid
|
|
case nil:
|
|
return StreamType.invalid
|
|
case .some(.none):
|
|
return StreamType.invalid
|
|
@unknown default:
|
|
return StreamType.invalid
|
|
}
|
|
}
|
|
|
|
func getFlutterMediaTracks(mediaTracks: [GCKMediaTrack]?) -> [MediaTrack]? {
|
|
if (mediaTracks == nil) {
|
|
return nil
|
|
}
|
|
|
|
var result = [MediaTrack]()
|
|
mediaTracks?.forEach({ (track: GCKMediaTrack) in
|
|
let resultTrack = getFlutterMediaTrack(mediaTrack: track)
|
|
result.append(resultTrack)
|
|
})
|
|
return result
|
|
}
|
|
|
|
func getFlutterMediaTrack(mediaTrack: GCKMediaTrack) -> MediaTrack {
|
|
let result = MediaTrack()
|
|
|
|
result.contentId = mediaTrack.contentIdentifier
|
|
result.id = NSNumber(value: mediaTrack.identifier)
|
|
result.language = mediaTrack.languageCode
|
|
result.name = mediaTrack.name
|
|
result.trackType = getFlutterTrackType(trackType: mediaTrack.type)
|
|
result.trackSubtype = getFlutterTrackSubtype(trackSubtype: mediaTrack.textSubtype)
|
|
|
|
return result
|
|
}
|
|
|
|
func getFlutterAdBreakClips(adBreakClips: [GCKAdBreakClipInfo]?) -> [AdBreakClipInfo]? {
|
|
if (adBreakClips == nil) {
|
|
return nil
|
|
}
|
|
|
|
var result = [AdBreakClipInfo]()
|
|
adBreakClips?.forEach({ (info: GCKAdBreakClipInfo) in
|
|
let resultInfo = getFlutterAdBreakClipInfo(adBreakClipInfo: info)
|
|
result.append(resultInfo)
|
|
})
|
|
return result
|
|
}
|
|
|
|
func getFlutterAdBreakClipInfo(adBreakClipInfo: GCKAdBreakClipInfo) -> AdBreakClipInfo {
|
|
let result = AdBreakClipInfo()
|
|
|
|
result.id = adBreakClipInfo.adBreakClipID
|
|
result.title = adBreakClipInfo.title
|
|
result.contentId = adBreakClipInfo.contentID
|
|
result.contentUrl = adBreakClipInfo.contentURL?.absoluteString
|
|
result.clickThroughUrl = adBreakClipInfo.clickThroughURL?.absoluteString
|
|
result.durationMs = getStreamDuration(streamDuration: adBreakClipInfo.duration)
|
|
result.imageUrl = adBreakClipInfo.posterURL?.absoluteString
|
|
result.mimeType = adBreakClipInfo.mimeType
|
|
result.whenSkippableMs = getFlutterWhenSkippableMs(whenSkippable: adBreakClipInfo.whenSkippable)
|
|
|
|
return result
|
|
}
|
|
|
|
func getFlutterTrackType(trackType: GCKMediaTrackType) -> TrackType {
|
|
switch trackType {
|
|
|
|
case .unknown:
|
|
return TrackType.unknown
|
|
case .text:
|
|
return TrackType.text
|
|
case .audio:
|
|
return TrackType.audio
|
|
case .video:
|
|
return TrackType.video
|
|
@unknown default:
|
|
return TrackType.unknown
|
|
}
|
|
}
|
|
|
|
func getFlutterTrackSubtype(trackSubtype: GCKMediaTextTrackSubtype) -> TrackSubtype {
|
|
switch trackSubtype {
|
|
|
|
case .unknown:
|
|
return TrackSubtype.unknown
|
|
case .subtitles:
|
|
return TrackSubtype.subtitles
|
|
case .captions:
|
|
return TrackSubtype.captions
|
|
case .descriptions:
|
|
return TrackSubtype.descriptions
|
|
case .chapters:
|
|
return TrackSubtype.chapters
|
|
case .metadata:
|
|
return TrackSubtype.metadata
|
|
@unknown default:
|
|
return TrackSubtype.unknown
|
|
}
|
|
}
|
|
|
|
func getFlutterMediaMetadata(mediaMetadata: GCKMediaMetadata?) -> MediaMetadata {
|
|
let result = MediaMetadata()
|
|
|
|
result.mediaType = getFlutterMediaType(mediaType: mediaMetadata?.metadataType)
|
|
result.webImages = []
|
|
|
|
mediaMetadata?.images().forEach({ (imageAny: Any) in
|
|
let image = imageAny as? GCKImage
|
|
if (image == nil) {
|
|
return
|
|
}
|
|
|
|
let webImage = WebImage()
|
|
webImage.url = image?.url.absoluteString
|
|
result.webImages?.append(webImage)
|
|
})
|
|
|
|
return result
|
|
}
|
|
|
|
func getFlutterMediaType(mediaType: GCKMediaMetadataType?) -> MediaType {
|
|
switch mediaType {
|
|
case .generic:
|
|
return MediaType.generic
|
|
case .movie:
|
|
return MediaType.movie
|
|
case .tvShow:
|
|
return MediaType.tvShow
|
|
case .musicTrack:
|
|
return MediaType.musicTrack
|
|
case .photo:
|
|
return MediaType.photo
|
|
case .audioBookChapter:
|
|
return MediaType.audiobookChapter
|
|
case .user:
|
|
return MediaType.user
|
|
case .none:
|
|
return MediaType.generic
|
|
@unknown default:
|
|
return MediaType.generic
|
|
}
|
|
}
|
|
|
|
func getFlutterMediaQueueItem(item: GCKMediaQueueItem?) -> MediaQueueItem {
|
|
let result = MediaQueueItem()
|
|
|
|
if (item == nil) {
|
|
result.itemId = -1
|
|
} else {
|
|
result.itemId = NSNumber(value: item?.itemID ?? 0)
|
|
}
|
|
|
|
result.autoplay = NSNumber(value: item?.autoplay ?? false)
|
|
result.playbackDuration = NSNumber(value: item?.playbackDuration ?? -1)
|
|
result.startTime = NSNumber(value: item?.startTime ?? 0)
|
|
result.preloadTime = NSNumber(value: item?.preloadTime ?? 0)
|
|
result.media = getFlutterMediaInfo(mediaInfo: item?.mediaInformation)
|
|
|
|
return result
|
|
}
|