diff --git a/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/FlutterCastFrameworkPlugin.kt b/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/FlutterCastFrameworkPlugin.kt index 30c56e7..b712e09 100644 --- a/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/FlutterCastFrameworkPlugin.kt +++ b/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/FlutterCastFrameworkPlugin.kt @@ -13,8 +13,8 @@ import com.gianlucaparadise.flutter_cast_framework.cast.MessageCastingChannel import com.gianlucaparadise.flutter_cast_framework.media.getFlutterMediaInfo import com.gianlucaparadise.flutter_cast_framework.media.getFlutterMediaStatus import com.gianlucaparadise.flutter_cast_framework.media.getMediaLoadRequestData +import com.gianlucaparadise.flutter_cast_framework.media.getMediaQueueItem import com.google.android.gms.cast.MediaError -import com.google.android.gms.cast.MediaStatus import com.google.android.gms.cast.MediaStatus.* import com.google.android.gms.cast.framework.CastContext import com.google.android.gms.cast.framework.CastSession @@ -341,6 +341,15 @@ class FlutterCastFrameworkPlugin : FlutterPlugin, MethodCallHandler, ActivityAwa remoteMediaClient.skipAd() } + override fun queueAppendItem(item: PlatformBridgeApis.MediaQueueItem?) { + if (item == null) return + + val remoteMediaClient: RemoteMediaClient = remoteMediaClient ?: return + + val mediaQueueItem = getMediaQueueItem(item) + remoteMediaClient.queueAppendItem(mediaQueueItem, null) + } + override fun setMute(muted: Boolean?) { if (muted == null) return val castSession = mCastSession ?: return diff --git a/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/media/HostMediaLoadRequestDataHelper.kt b/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/media/HostMediaLoadRequestDataHelper.kt index cac9837..3bd29e8 100644 --- a/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/media/HostMediaLoadRequestDataHelper.kt +++ b/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/media/HostMediaLoadRequestDataHelper.kt @@ -2,10 +2,7 @@ package com.gianlucaparadise.flutter_cast_framework.media import android.net.Uri import com.gianlucaparadise.flutter_cast_framework.PlatformBridgeApis -import com.google.android.gms.cast.MediaInfo -import com.google.android.gms.cast.MediaLoadRequestData -import com.google.android.gms.cast.MediaMetadata -import com.google.android.gms.cast.MediaTrack +import com.google.android.gms.cast.* import com.google.android.gms.common.images.WebImage import org.json.JSONObject @@ -140,3 +137,14 @@ fun getTrackSubtype(trackSubtype: PlatformBridgeApis.TrackSubtype): Int { PlatformBridgeApis.TrackSubtype.metadata -> 5 } } + +fun getMediaQueueItem(item: PlatformBridgeApis.MediaQueueItem?): MediaQueueItem? { + if (item?.media == null) return null + + val mediaInfo = getMediaInfo(item.media) + + return MediaQueueItem.Builder(mediaInfo) + .setAutoplay(item.autoplay) + .setPreloadTime(item.preloadTime) + .build() +} \ No newline at end of file diff --git a/ios/Classes/HostMediaLoadRequestDataHelper.swift b/ios/Classes/HostMediaLoadRequestDataHelper.swift index fe14985..f1742b4 100644 --- a/ios/Classes/HostMediaLoadRequestDataHelper.swift +++ b/ios/Classes/HostMediaLoadRequestDataHelper.swift @@ -183,3 +183,13 @@ func getCustomData(customDataAsString: String?) -> Any? { let data = customDataAsString!.data(using: .utf8)! return try? JSONSerialization.jsonObject(with: data, options: []) } + +func getMediaQueueItem(item: MediaQueueItem) -> GCKMediaQueueItem { + let mediaQueueItemBuilder = GCKMediaQueueItemBuilder.init() + + mediaQueueItemBuilder.mediaInformation = getMediaInfo(mediaInfo: item.media) + mediaQueueItemBuilder.autoplay = item.autoplay == 1 + mediaQueueItemBuilder.preloadTime = item.preloadTime?.doubleValue ?? 0 + + return mediaQueueItemBuilder.build() +} diff --git a/ios/Classes/SwiftFlutterCastFrameworkPlugin.swift b/ios/Classes/SwiftFlutterCastFrameworkPlugin.swift index 4069dec..33d2bc4 100644 --- a/ios/Classes/SwiftFlutterCastFrameworkPlugin.swift +++ b/ios/Classes/SwiftFlutterCastFrameworkPlugin.swift @@ -326,6 +326,19 @@ public class SwiftFlutterCastFrameworkPlugin: NSObject, FlutterPlugin, GCKSessio public func skipAdWithError(_ error: AutoreleasingUnsafeMutablePointer) { remoteMediaClient?.skipAd() } + + public func queueAppendItemItem(_ item: MediaQueueItem, error: AutoreleasingUnsafeMutablePointer) { + + let remoteMediaClient = castSession?.remoteMediaClient + if remoteMediaClient == nil { + return + } + + let mediaQueueItem = getMediaQueueItem(item: item) + // as per documentation: If beforeItemWithID is kGCKMediaQueueInvalidItemID, the inserted item will be appended to the end of the queue + remoteMediaClient?.queueInsert(mediaQueueItem, beforeItemWithID: kGCKMediaQueueInvalidItemID) + } + // MARK: - GCKSessionManagerListener // onSessionSuspended diff --git a/lib/src/cast/RemoteMediaClient.dart b/lib/src/cast/RemoteMediaClient.dart index a808d63..ab6ef9b 100644 --- a/lib/src/cast/RemoteMediaClient.dart +++ b/lib/src/cast/RemoteMediaClient.dart @@ -109,6 +109,11 @@ class RemoteMediaClient { _hostApi.skipAd(); } + /// Appends a new media item to the end of the queue. + void queueAppendItem(MediaQueueItem item) { + _hostApi.queueAppendItem(item); + } + /// Internal method that shouldn't be visible @internal void dispatchPlayerStateUpdate(PlayerState playerState) {