Tourenathan-G5organisation / SiliCompressor

A powerful, flexible and easy to use Video and Image compression library for Android.
Apache License 2.0
1.38k stars 292 forks source link

Video deforms after compression #90

Open Amanduzhuojiang opened 5 years ago

Amanduzhuojiang commented 5 years ago

Hi,@Toure Nathan I have found a problem that the video compression recorded by this mobile phone will not change.If you download video from somewhere else, and then you compress it, Video Height deformation,

Amanduzhuojiang commented 5 years ago

I get the width and height of video as follows: MediaMetadataRetriever mmr = new MediaMetadataRetriever(); mmr.setDataSource(path); String width = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH); String height = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);

And then call: SiliCompressor. With (MaijiaxiuSubmitEvaluationActivity. This). CompressVideo (video_path. The toString (), GlobalParams. LOCAL_SAVE_PATH, Integer. The parseInt (width), an Integer. The parseInt (height), 450000);

It's still going to deform

malwinder-s commented 5 years ago

I fixed it by:

val retriever = MediaMetadataRetriever()
                    retriever.setDataSource(videoPath)
                    val width = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH))
                    val height = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT))
                    val rotation = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION))

                    val compressedVideoFilePath =
                        SiliCompressor
                            .with(context)
                            .compressVideo(videoPath, context.cacheDir.path, if (rotation == 0) {
                            width
                        } else {
                            0
                        }, if (rotation == 0){
                            height
                        }else {
                            0
                        }, 450000)
ThirupathiMukkera commented 5 years ago

Which bitrate is better for captured videos from camera to compress.

RodneyOssai commented 4 years ago

The deformation happens because of the way the Android system stores the width and height parameters. If you hold your phone and look at it , even a blind man knows that the width of the phone screen is shorter than the height of the phone screen.

For example, but when you use MediaMetadataRetriever() to retrieve video data of a video 640 x 360 what media data gives is width = 640 and Height = 360 which is a lie because in real life the width of your video is 360 the shorter side.

Why does this stretching or deformation occur?

The person who coded this compressor noticed that Android System swaps the width and height parameters gotten from MediaRetreiver so this is the code he used inside his compressor he swaps it back to the correct this blunder.

        String width = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);

        String height = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);

        String rotation = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);

Normally this fixes the problem. But if you download a video from the internet or video not made by the Android system, The width and height parameters are stored properly and the code that the owner of the compressor wrote is now the one swapping width and height and distorting your video. how to fix it We always expect the width of the video to be smaller than the height in android phone. ie 9:16 instead if 16:9 So Add this line of code to fix it:

 String width = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);

        String height = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);

        String rotation = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);

if ((width > height) && (rotationValue == 0)) {
            //We Prefer that the video width be less than the video height in Android so swap values if width is greater.
            int tempHeight = originalHeight;
            int tempWidth = originalWidth;
            originalHeight = tempWidth;
            originalWidth = tempHeight;
        }

Now you can call

SiliCompressor.with(context)
                            .compressVideo(sourcepath,destDir+"filename.mp4",outWidth,outheight,bitrate);
Tourenathan-G5organisation commented 3 years ago

@RodneyOssai very good analysis of the library, thanks for your suggestion. I plan to integrate a method which will be used to compress videos captured by the phone and other use to compress other videos. Thanks for the feedback

Krutika-chotara commented 3 years ago

My video is downloaded from internet. and real width is 1920 and height is 1080, rotation is 0. After compression video width is 1080 and height is 1920. i am using same logic.