androidx / media

Jetpack Media3 support libraries for media use cases, including ExoPlayer, an extensible media player for Android
https://developer.android.com/media/media3
Apache License 2.0
1.69k stars 405 forks source link

Will support for generating thumbnails be added? #360

Open DeVictorVH opened 1 year ago

DeVictorVH commented 1 year ago

Exoplayer should allow getting media thumbnails to display in a list of videos like in a recyclerview for example, so you don't have to resort to ThumbnailUtils, MediaMetadataRetriever, etc. because these have limited compatibility.

rohitjoins commented 1 year ago

Hi @DeVictorVH,

Currently Exoplayer does not provide an API to generate thumbnails and we don't have a plan to do so in the near future.

We are open to accepting high quality PR's which adds support for fetching thumbnails from a media source type e.g., support for thumbnails in DASH.

I'll leave the issue open and mark it as an enhancement with low priority. Thanks.

ionictest2017 commented 2 months ago

hello I have extracted the thumbnail from the MPD manifest but I am unable to show a single tile from the image I am getting bellow information

URL: https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel-tiled-thumbnails-timeline.ism/dash/tears-of-steel-tiled-thumbnails-timeline-img=4000-t-0.jpg width: 224 height: 100 horizontal: 3 vertical: 4 row: 0 column: 1

here is my code

` private void extractCurrentFrameThumbnail(ExoPlayer player, Timeline timeline) { DashManifest manifest = (DashManifest) player.getCurrentTimeline().getWindow(0, new Timeline.Window()).manifest; if (manifest == null) { return; }

    // Get the current playback position in microseconds
    long playbackPositionUs = player.getCurrentPosition() * 1000;

    for (int i = 0; i < manifest.getPeriodCount(); i++) {
        Period period = manifest.getPeriod(i);
        long periodDurationUs = manifest.getPeriodDurationUs(i);

        for (int j = 0; j < period.adaptationSets.size(); j++) {
            AdaptationSet adaptationSet = period.adaptationSets.get(j);

            for (int k = 0; k < adaptationSet.representations.size(); k++) {
                Representation representation = adaptationSet.representations.get(k);
                String mimeType = representation.format.containerMimeType;

                if ("image/jpeg".equals(mimeType)) {
                    Representation.MultiSegmentRepresentation multiSegmentRepresentation =
                        (Representation.MultiSegmentRepresentation) representation;

                    long segmentIndex = multiSegmentRepresentation.getSegmentNum(playbackPositionUs, periodDurationUs);

                    if (segmentIndex >= 0 && segmentIndex < multiSegmentRepresentation.getSegmentCount(periodDurationUs)) {
                        String baseUrl = representation.baseUrls.get(0).url;

                        // Get the segment URL
                        RangedUri segmentUri = multiSegmentRepresentation.getSegmentUrl(segmentIndex);

                        if (segmentUri != null) {
                            String thumbnailUrl = segmentUri.resolveUri(baseUrl).toString();

                            // Get metadata
                            Format format = representation.format;
                            int imageWidth = format.width;
                            int imageHeight = format.height;
                            int tileCountHorizontal = format.tileCountHorizontal;
                            int tileCountVertical = format.tileCountVertical;

                            // Calculate the width and height of each tile
                            int tileWidth = imageWidth / tileCountHorizontal;
                            int tileHeight = imageHeight / tileCountVertical;

                            // Determine the tile index within the segment
                            int tileIndex = (int) (segmentIndex % (tileCountHorizontal * tileCountVertical));
                            int tileRow = tileIndex / tileCountHorizontal;
                            int tileColumn = tileIndex % tileCountHorizontal;

                            // Log the tile position and URL
                            String logMessage = String.format(
                                "url: %s Image.width: %d Image.height: %d tile.horiz: %d tile.vert: %d tile.row: %d tile.column: %d",
                                thumbnailUrl,
                                tileWidth,
                                tileHeight,
                                tileCountHorizontal,
                                tileCountVertical,
                                tileRow,
                                tileColumn
                            );
                            System.out.println(logMessage);

                            // This would be the log line to use in Android:
                            // Log.d(TAG, logMessage);
                        } else {
                            System.out.println("No segment URL found for the current frame.");
                        }
                    } else {
                        System.out.println("Current playback position does not match any segment.");
                    }

                    return;
                }
            }
        }
    }
}`

can anyone help me show a single tile from the multiple-tiled image

thanks