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

MediaItemConverter does not convert MediaQueueItem to MediaItem #8212

Open
roubertedgar opened this issue Nov 12, 2020 · 8 comments
Open

MediaItemConverter does not convert MediaQueueItem to MediaItem #8212

roubertedgar opened this issue Nov 12, 2020 · 8 comments
Assignees

Comments

@roubertedgar
Copy link

roubertedgar commented Nov 12, 2020

Hi, I am working with CastPlayer and I have some questions about the recovery of the current session.
The scenario is:

  • I start the cast and the content is played on TV
  • Then I finish my application, killing the whole process.
  • After that, the content still playing on TV, and then, i start my app again
  • The CastPlayer is able to recover the session, with MeduaQueueItem on the RemoteMediaClient.

The problem here is; the MediaItem currentMediaItem present in the Player interface is not recovered correctly, coming with empty fields. I was looking at the codes, in the MediaItemConverter and realised that the method toMediaItem (MediaQueueItem mediaQueueItem) is called only on tests. Is it possible to make CastPlayer use this method and be able to set the currentMediaItem correctly? This would be helpful, as it would make it easier to check if a content that i'am opening was already being played on TV before the session was recovered by reopening the application.

Today, i need to access the CastContext to recover the session and then convert the MediaQueueItem to MediaItem:

        val mediaItem =
            castContext?.sessionManager?.currentCastSession?.remoteMediaClient?.currentItem?.let {
                mediaItemConverter.toMediaItem(it)
            }

        return isPlaying() && content.contentId() == mediaItem?.mediaId

Thanks.

@makp9k
Copy link

makp9k commented Mar 7, 2021

Same here, any updates? I can not find a way to alter the CastPlayer behavior in any way since it is not extendable, we can not override timeline implementation or something like this. So for now I also stuck with this kind of workaround, which I don't really like. Thanks!

@marcbaechinger
Copy link
Contributor

marcbaechinger commented Mar 8, 2021

I marked this issue as enhancement. We should convert MediaQueueItems that are coming in from cast to MediaItems, and then update the CastTimteline appropriately. The conversion should be done by the MediaItemConverter that can be customized by apps by injecting it's own version into CastPlayer. DefaultMediaItemConverter should make this process work so that eg. the uri is shared with the case device and in the other direction. Metadata will likely be left not converted back and forth because mapping the meta data is not as straightforward as it looks like (see #8669 also).

Thanks for your comment @makp9k

Are you looking for altering the CastPlayer behaviour in any other way than what is provided with MediaItemConverter? I mean, assumend the converter is also converting MediaQueueItems from a cast device to show up in the CastTmeline which the CastPlayer is using (see this issue and my paragraph above in this comment). Besides this, is there anything else you are missing? (I also assume you are aware that you can inject your custom MediaItemConverter as mentioned in ##8669)

@makp9k
Copy link

makp9k commented Mar 9, 2021

If CastPlayer will properly call toMediaItem, then it would be totally sufficient for my needs. I was just looking for a way to hook into MediaItems conversion process until this issue is resolved and realised there is not much we can do about the CastPlayer in general. Thank you!

@n0m0r3pa1n
Copy link

Currently, CastTimeline doesn't care about MediaItem and it works only with itemIds and also with this ItemData(long durationUs, long defaultPositionUs, boolean isLive). It is really bad in terms of currentMediaItem behavior, especially this method

@Override
  public Window getWindow(int windowIndex, Window window, long defaultPositionProjectionUs) {
    long durationUs = durationsUs[windowIndex];
    boolean isDynamic = durationUs == C.TIME_UNSET;
    MediaItem mediaItem =
        new MediaItem.Builder().setUri(Uri.EMPTY).setTag(ids[windowIndex]).build();
    return window.set(
        /* uid= */ ids[windowIndex],
        /* mediaItem= */ mediaItem,
        /* manifest= */ null,
        /* presentationStartTimeMs= */ C.TIME_UNSET,
        /* windowStartTimeMs= */ C.TIME_UNSET,
        /* elapsedRealtimeEpochOffsetMs= */ C.TIME_UNSET,
        /* isSeekable= */ !isDynamic,
        isDynamic,
        isLive[windowIndex] ? mediaItem.liveConfiguration : null,
        defaultPositionsUs[windowIndex],
        durationUs,
        /* firstPeriodIndex= */ windowIndex,
        /* lastPeriodIndex= */ windowIndex,
        /* positionInFirstPeriodUs= */ 0);
  }

Setting an empty mediaItem with only the index as a tag is such a hidden thing. Please, at least comment such stuff.

@n0m0r3pa1n
Copy link

@marcbaechinger this is kind of a bug? CurrentMediaItem is always empty one, it is not returned correctly.

@AquilesCanta
Copy link
Contributor

The reason for which we are not bringing in the Timeline from the receiver is that the Cast default receiver does not behave reliably, so that we can guarantee a consistent state across all senders and the receiver. I've recently revisited this, but I haven't been able to make progress. If you have some time to invest in this, I encourage you to send a pull request. It will be more than welcome.

rohitjoins pushed a commit to androidx/media that referenced this issue Jul 12, 2022
The media item needs to be assigned to `Window.mediaItem` in `CastTimeline.setWindow`. For this the `MediaItem` needs to be available in the timeline.

When a `MediaItem` is passed to the `set/addMediaItems` method, we can't yet know the Cast `MediaQueueItem.itemId` that is generated on the device and arrives with an async update of the `RemoteMediaClient` state. Hence in the `CastTimelineTracker`, we need to store the `MediaItem` by Casts's `MediaItem.contentId`. When we then receive the updated queue, we look the media item up by the content ID to augment the `ItemData` that is available in the `CastTimeline`.

Issue: #25
Issue: google/ExoPlayer#8212

#minor-release

PiperOrigin-RevId: 460325235
rohitjoins pushed a commit that referenced this issue Jul 12, 2022
The media item needs to be assigned to `Window.mediaItem` in `CastTimeline.setWindow`. For this the `MediaItem` needs to be available in the timeline.

When a `MediaItem` is passed to the `set/addMediaItems` method, we can't yet know the Cast `MediaQueueItem.itemId` that is generated on the device and arrives with an async update of the `RemoteMediaClient` state. Hence in the `CastTimelineTracker`, we need to store the `MediaItem` by Casts's `MediaItem.contentId`. When we then receive the updated queue, we look the media item up by the content ID to augment the `ItemData` that is available in the `CastTimeline`.

Issue: androidx/media#25
Issue: #8212

#minor-release

PiperOrigin-RevId: 460325235
@tonihei
Copy link
Collaborator

tonihei commented Jul 15, 2022

Fixed by the commits above.

@tonihei tonihei closed this as completed Jul 15, 2022
@marcbaechinger
Copy link
Contributor

I think we need #9078 also to have this properly working.

rohitjoins pushed a commit that referenced this issue Jul 15, 2022
The media item needs to be assigned to `Window.mediaItem` in `CastTimeline.setWindow`. For this the `MediaItem` needs to be available in the timeline.

When a `MediaItem` is passed to the `set/addMediaItems` method, we can't yet know the Cast `MediaQueueItem.itemId` that is generated on the device and arrives with an async update of the `RemoteMediaClient` state. Hence in the `CastTimelineTracker`, we need to store the `MediaItem` by Casts's `MediaItem.contentId`. When we then receive the updated queue, we look the media item up by the content ID to augment the `ItemData` that is available in the `CastTimeline`.

Issue: androidx/media#25
Issue: #8212

#minor-release

PiperOrigin-RevId: 460325235
(cherry picked from commit 02e1484)
rohitjoins pushed a commit to androidx/media that referenced this issue Jul 15, 2022
The media item needs to be assigned to `Window.mediaItem` in `CastTimeline.setWindow`. For this the `MediaItem` needs to be available in the timeline.

When a `MediaItem` is passed to the `set/addMediaItems` method, we can't yet know the Cast `MediaQueueItem.itemId` that is generated on the device and arrives with an async update of the `RemoteMediaClient` state. Hence in the `CastTimelineTracker`, we need to store the `MediaItem` by Casts's `MediaItem.contentId`. When we then receive the updated queue, we look the media item up by the content ID to augment the `ItemData` that is available in the `CastTimeline`.

Issue: #25
Issue: google/ExoPlayer#8212

#minor-release

PiperOrigin-RevId: 460325235
(cherry picked from commit 30fbc3a)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants