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.52k stars 363 forks source link

Using Media3 Transformer library, Want to get the video duration and size by passing the start and end Milliseconds Out of the complete video file. #1304

Closed NagaMoto57 closed 1 month ago

NagaMoto57 commented 4 months ago

Hi Team,

By passing Start and End Millisecond's, I want to get the duration and size of that particular portion (Between Start and End) of the video using Media3 transformer library.

Can you please help in providing the required details on above.

Thanks.

droid-girl commented 4 months ago

Hi! could you share in more detail what you are trying to achieve or your use case for this functionality?

NagaMoto57 commented 4 months ago

Hello, The use case is video trimming same as whats app. Where user can send only the required portion of the video. For the user, Want to show the duration and size of the selected portion out of complete video. So that, He can adjust the positions again if the size is more.

Pls suggest what I can use here to achieve.

Thanks in-advance.

droid-girl commented 4 months ago

In Transformer, to clip media, you need to use ClippingConfiguration and provide start and end position for the clipping like here. You should be able to calculate the duration of the clip by using end and start position for the trim without the need for any API from Transformer. For the size, I think in whatsapp they do an estimation of the size depending on the original video size. If you only what to trim a media asset, you could probably just estimate the size by using proportions. If you are applying any other effects or transcoding to a different size or resolution, the estimates will be off. Transformer APIs do not provide any size estimate for the output file.

NagaMoto57 commented 4 months ago

If you only what to trim a media asset, you could probably just estimate the size by using proportions. : How I can achieve this ? I will not be applying any other effects or resolution. I just want to show the size of the result video for User info.

calren commented 4 months ago

For example, if the original video is 30 seconds and 30mb, and the trimmed video is 10 seconds (1/3 of the original video), then you can probably estimate that the trimmed video will be around 10mb (also 1/3 of the original video).

A simple equation for calculating this would be something like: (duration of trimmed video / duration of original video) * size of original video

NagaMoto57 commented 4 months ago

(duration of trimmed video / duration of original video) * size of original video I tried the above equation. I could observe their is more difference between the above equation value and the result video size. I tried with one video, The details are below. Original Video duration - 2:51 Original video size - 31.49 mb Trim duration - 00:08 The equation value is : 1.4 mb, But the media3 ClippingConfiguration result video file size is 3.71 mb startMs : 101073, endMs : 109281 Code snippet used for trimming is below : MediaItem inputMediaItem = new MediaItem.Builder() .setUri(source) .setClippingConfiguration( new MediaItem.ClippingConfiguration.Builder() .setStartPositionMs(startMs) .setEndPositionMs(endMs) .build()) .build(); EditedMediaItem editedMediaItem = new EditedMediaItem.Builder(inputMediaItem) .build(); transformer = new Transformer.Builder(DroidApiManager.getApplicationContext()) .addListener(transformerListener) .build(); Logger.d(TAG, "new compression transformer : "+transformer); transformer.start(editedMediaItem, destination);

I observed Data rate and Total bitrate values are different in original video and the trimmed video. Original video - Data rate : 1085 kbps, total bitrate : 1468 kbps Trimmed video - Data rate : 3489 kbps, total bitrate : 3885 kbps How can I apply the same data rate / total bitrate as original in ClippingConfiguration for the trimming. So that original video and trimmed video will have same data rate and total bitrate. Pls Help. Thanks.

calren commented 4 months ago

Is the issue you're trying to solve that the estimated size of the trimmed result video is not accurate?

Unfortunately I don't think there's a good solution for estimating the exact size of a trimmed video.

I believe Whatsapp is only using an estimation when calculating video size. Our testing with Whatsapp showed that the actual size of a trimmed video was different than the estimated size.

NagaMoto57 commented 4 months ago

Is the issue you're trying to solve that the estimated size of the trimmed result video is not accurate? : YES

Please help me to achieve the below.

I observed Data rate and Total bitrate values are different in original video and the trimmed video. Original video - Data rate : 1085 kbps, total bitrate : 1468 kbps Trimmed video - Data rate : 3489 kbps, total bitrate : 3885 kbps How can I apply the same data rate / total bitrate as original in ClippingConfiguration for the trimming. So that original video and trimmed video will have same data rate and total bitrate. Pls Help. Thanks.

droid-girl commented 4 months ago

To start with, there is a lot of parameters you need to take into account to achieve the best estimate. To answer your question, you can set target bitrate by setting EncoderFactory as described here. However, there are a lot of other factors to consider: 1) If you are trimming only from the end of the clip and the input format is matched the configuration export, Transformer would switch to transmuxing. 2) Review you Transformer settings and set VideoMimeType and AudioMimeType that is matching your input. 3) There is a new experimental method that would switch to transmuxing for start and end trimming in the case when the output format matches the input format and a few other parameters. This optimization will only transmux a fraction of your trims that contains start trim operation. More information can be found here

NagaMoto57 commented 3 months ago

Hi Team,

Thanks for the update. To answer your question, you can set target bitrate by setting EncoderFactory as described https://github.com/androidx/media/issues/1154#issuecomment-1986591491.

I tried the above answer to set the bitrate. But I observed the result video is having the higher value than the setBitrate value. Q : Is their a logic of any fixed bitrate will be taken based on the resolution irrespective of setBitrate value ? Q : Pls let me know why the trimmed video is not having the bitrate as setBitrate value. Code snippet used for trimming:
MediaItem inputMediaItem = new MediaItem.Builder() .setUri(source) .setClippingConfiguration( new MediaItem.ClippingConfiguration.Builder() .setStartPositionMs(startMs) .setEndPositionMs(endMs) .build()) .build(); EditedMediaItem editedMediaItem = new EditedMediaItem.Builder(inputMediaItem) .build(); transformer = new Transformer.Builder(context) .setEncoderFactory(new DefaultEncoderFactory.Builder(context) .setRequestedVideoEncoderSettings( new VideoEncoderSettings.Builder() .setBitrate(bitRateToApply) .build()) .build()) .addListener(new Transformer.Listener() { @Override public void onCompleted(Composition composition, ExportResult exportResult) { } @Override public void onError(Composition composition, ExportResult result, ExportException exception) { } }) .build(); transformer.start(editedMediaItem, destination);

I am getting the bitrate value of original video by using the below api : MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever(); try { mediaMetadataRetriever.setDataSource(url); return Integer.parseInt(mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_BITRATE)); } catch (NumberFormatException e) { return 0; }

ychaparov commented 3 months ago

Hi @NagaMoto57 ! Sorry for the delayed reply.

Depending on your phone, video contents and bitrate value you're setting, you might see actual file bitrates overshooting your input parameter. More details here: https://developer.android.com/reference/android/media/MediaCodec#qualityFloor . This logic is part of the system MediaCodec and is intended to preserve visual quality, based on the input video.

If you really need to hit a fixed bitrate target, at the expense of visual quality, you can switch to Constant Bitrate (CBR) mode. Something like this:

                    new DefaultEncoderFactory.Builder(context)
                        .setRequestedVideoEncoderSettings(
                            new VideoEncoderSettings.Builder()
                                .setBitrate(bitrate)
                                .setBitrateMode(BITRATE_MODE_CBR)
                                .build())

If your bitrate frequently overshoots the VBR bitrate target, you'r probably using a resolution that's too high for your video & bitrate. Perhaps you can try encoding at a lower resolution:

    new EditedMediaItem.Builder(MediaItem.fromUri(uri))
        .setEffects(
            new Effects(
                /* audioProcessors= */ ImmutableList.of(),
                /* videoEffects= */ ImmutableList.of(Presentation.createForHeight(480))))
        .build();
droid-girl commented 3 months ago

@NagaMoto57 please let us know if this suggestion works for you

NagaMoto57 commented 3 months ago

Hi, Thanks for the info. I am middle of checking the info, I will come back. Thanks.

google-oss-bot commented 1 month ago

Hey @NagaMoto57. We need more information to resolve this issue but there hasn't been an update in 14 weekdays. I'm marking the issue as stale and if there are no new updates in the next 7 days I will close it automatically.

If you have more information that will help us get to the bottom of this, just add a comment!

google-oss-bot commented 1 month ago

Since there haven't been any recent updates here, I am going to close this issue.

@NagaMoto57 if you're still experiencing this problem and want to continue the discussion just leave a comment here and we are happy to re-open this.