如何在Android上确定视频的宽度和高度

28

我有一个视频文件,想要获取视频的宽度和高度。我不想播放视频,只是想获取大小。我尝试使用MediaPlayer:

MediaPlayer mp = new MediaPlayer();
mp.setDataSource(uriString);
mp.prepare();
int width = mp.getVideoWidth();
int height = mp.getVideoHeight();

但是它返回宽度和高度为0,因为VideoSizeChangedEvent尚未触发。

我如何获取视频的宽度和高度?

更新:我需要API版本7。

8个回答

46

这适用于 API 级别 10 及以上:

MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource("/path/to/video.mp4");
int width = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH));
int height = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT));
retriever.release();

@TigranSarkisian 这个应用在安卓6.0上会崩溃吗? - Karthik K M
1
如果API版本是10或以上,则代码能够正常运行。但如果路径无效或文件不存在,则会抛出“IllegalArgumentException”异常。 - Emre Aydin
1
适用于安卓7.1。 - Vlad
1
应该使用 parseInt() 方法而不是 valueOf。无论如何,你救了我的一天! - Tom3652
retriever.setDataSource不起作用。 - Carlos López Marí

22

在某些情况下,我们无法读取元数据。为了确保获取宽度和高度,最好使用 MediaMetadataRetriever 创建一个 Bitmap,然后从创建的 Bitmap 中获取宽度和高度,如下所示:

public int getVideoWidthOrHeight(File file, String widthOrHeight) {
    MediaMetadataRetriever retriever = null;
    Bitmap bmp = null;
    FileInputStream inputStream = null;
    int mWidthHeight = 0;                                                                                                                
    try {
        retriever = new  MediaMetadataRetriever();
        inputStream = new FileInputStream(file.getAbsolutePath());
        retriever.setDataSource(inputStream.getFD());
        bmp = retriever.getFrameAtTime();
        if (widthOrHeight.equals("width")){
            mWidthHeight = bmp.getWidth();
        }else {
            mWidthHeight = bmp.getHeight();
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (RuntimeException e) {
        e.printStackTrace();
    } finally{
       if (retriever != null){
           retriever.release()
       }if (inputStream != null){
           inputStream.close()
       }
    }  
    return mWidthHeight;
}

您可以像这样调用上述方法:

// Get the video width
int mVideoWidth = getVideoWidthOrHeight(someFile, "width");
// Get the video height
int mVideoHeight = getVideoWidthOrHeight(someFile, "height");

抱歉,我忘记写了,我需要API版本7,因此没有MediaMetadataRetriever。 - mao
谢谢你提供的代码,但是我不知道如何获取项目中res/raw文件夹中文件的适当字符串,有什么建议吗? - Lennert

14

这对我起作用了

videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(final MediaPlayer mp) {
                int width = mp.getVideoWidth();
                int height = mp.getVideoHeight();
            }
        });

当从某些URL获取视频的高度和宽度时,应用程序会卡住,如果无法从视频中获取高度和宽度,应用程序也会卡住。 - Kishan Viramgama
1
对我有效的唯一方法是 - MediaMetadataRetriever 似乎不太了解视频尺寸... - slott

7

API级别7的解决方案:

// get video dimensions
MediaPlayer mp = new MediaPlayer();
        try {
            mp.setDataSource(filename);
            mp.prepare();
            mp.setOnVideoSizeChangedListener(new OnVideoSizeChangedListener() {
                @Override
                public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {

                    int orient = -1;

                    if(width < height)
                        orient = 1;
                    else
                        orient = 0;

                }
            });
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

当从某些URL获取视频的高度和宽度时,应用程序会卡住,如果无法从视频中获取高度和宽度,应用程序也会卡住。 - Kishan Viramgama

1
这是一组与Android中Size抽象相关的实用工具(set of utilities)
其中包含一个名为SizeFromVideoFile.java的类。 您可以像这样使用它:
ISize size = new SizeFromVideoFile(videoFilePath);
size.width();
size.hight();

0
private static final Uri MOVIE_URI = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
private static final String[] MOVIE_PJT = new String[] {
        MediaStore.Video.Media._ID, MediaStore.Video.Media.DATA,
        MediaStore.Video.Media.TITLE, MediaStore.Video.Media.DATE_TAKEN,
        MediaStore.Video.Media.MIME_TYPE, MediaStore.Video.Media.DURATION,
        MediaStore.Video.Media.SIZE, MediaStore.Video.Media.RESOLUTION };

尝试使用系统内容提供程序查询。它将返回一些有用的视频(本地文件)信息。


至少有时,“RESOLUTION”为空。(我还不确定何时它是非空的,但我遇到了这个问题,寻找一种在“RESOLUTION”不可用时获取分辨率的方法(可惜只适用于Gingerbread及以上版本)。 - Jon Shemitz

0

Kotlin版本

data class VideoSize(val width: Int, val height: Int)

扩展函数

fun Uri.getVideoSize(): VideoSize {
        val retriever = MediaMetadataRetriever()
        retriever.setDataSource(appContext, this)
        val width =
            retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH)?.toInt() ?: 0
        val height =
            retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT)?.toInt() ?: 0
        retriever.release()
        return VideoSize(width, height)
    }

0
我的应用程序中使用的Kotlin版本是参考了user493244的答案。
     /**
     * determine video width and height
     *
     *
     * Refer to [stackoverflow](https://dev59.com/UGox5IYBdhLWcg3wpFv5)
     * answer of  [user493244](https://stackoverflow.com/users/493244/user493244)
     *
     * @param file string with file pathname to use
     * @param widthOrHeight string with size required (width or height)
     * @return mWidthHeight int with video width or height
     */
    fun getVideoWidthOrHeight(file: String?, widthOrHeight: String): Int {
        var retriever: MediaMetadataRetriever? = null
        val bmp: Bitmap?
        //
        var mWidthHeight = 0
        try {
            retriever = MediaMetadataRetriever()
            //
            retriever.setDataSource(file)
            bmp = retriever.frameAtTime
            mWidthHeight = if (widthOrHeight == getString(R.string.width)) {
                bmp!!.width
            } else {
                bmp!!.height
            }
        } catch (e: RuntimeException) {
            e.printStackTrace()
        } finally {
            if (retriever != null) {
                try {
                    retriever.release()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
            }
        }
        return mWidthHeight
    }    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接