【Androidでデータやファイルと戯れる】MediaMetadataRetrieverを使ってファイルのメタデータや動画のキャプチャの取得する

このエントリーを Google ブックマーク に追加
Pocket
[`yahoo` not found]

今回はMediaMetadataRetrieverの使い方を説明します。
このクラスを使ってできることは下記のとおりです。
  • メディアファイルのメタデータを取得する。
  • 動画のキャプチャを取得する。
使い方は特に難しくなく対象のメディアファイルを指定し、メタデータや動画のキャプチャを取得します。
下記は動画を取得し、メタデータを表示、一秒ごとのキャプチャをリスト表示をするサンプルです。
やはり、メモリを多く消費し処理時間がかかることに注意しないといけないです。
public class MainActivity extends AppCompatActivity {

    private static final int REQUEST_VIDEO_CAPTURE = 100;

    private ArrayList<Bitmap> bitmapArrayList = new ArrayList<>();

    private ListView gridView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LinearLayout linearLayout = new LinearLayout(getApplicationContext());
        linearLayout.setOrientation(LinearLayout.VERTICAL);
        Button button = new Button(getApplicationContext());
        button.setText("動画を撮る");
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // カメラアプリ起動
                Intent intent = new Intent();
                intent.setAction(MediaStore.ACTION_VIDEO_CAPTURE);
                intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
                startActivityForResult(intent, REQUEST_VIDEO_CAPTURE);
            }
        });
        linearLayout.addView(button);
        gridView = new ListView(getApplicationContext());
        linearLayout.addView(gridView);
        setContentView(linearLayout);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_VIDEO_CAPTURE && resultCode == RESULT_OK) {
            showMetadata(data.getData());
        } else {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }

    private void showMetadata(Uri uri) {
        // メディアメタデータにアクセスするクラスをインスタンス化する。
        MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();

        /**
        * メタデータを取得するファイルを指定する。
        * アクセスするためにはまずMediaMetadataRetriever#setDataSourceを呼ぶ必要があります。
        * このメソッドはいくつかのオーバーロードがありますが、
        * URIで指定するかファイルパスを指定する方法がメインかなと思います。
        */
        mediaMetadataRetriever.setDataSource(getApplicationContext(), uri);

        /**
        * メタデータにアクセスします。
        * 設定されていない場合はnullが返ってきます。
        */
        Log.d("MediaMetadataRetriever", "アルバム名:" + mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM));
        Log.d("MediaMetadataRetriever", "アルバムアーティスト名:" + mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST));
        Log.d("MediaMetadataRetriever", "アーティスト名:" + mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST));
        Log.d("MediaMetadataRetriever", "著者名:" + mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_AUTHOR));
        Log.d("MediaMetadataRetriever", "ビットレート(bits/sec):" + mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_BITRATE));
        Log.d("MediaMetadataRetriever", "キャプチャフレームレート:" + mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_CAPTURE_FRAMERATE));
        Log.d("MediaMetadataRetriever", "オーディオデータの順序:" + mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER));
        Log.d("MediaMetadataRetriever", "音楽ファイルの編集状態:" + mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_COMPILATION));
        Log.d("MediaMetadataRetriever", "作曲家情報:" + mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_COMPOSER));
        Log.d("MediaMetadataRetriever", "ファイル作成日:" + mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DATE));
        Log.d("MediaMetadataRetriever", "わからない:" + mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DISC_NUMBER));
        Log.d("MediaMetadataRetriever", "再生時間(ms):" + mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));
        Log.d("MediaMetadataRetriever", "カテゴリタイプ・ジャンル:" + mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_GENRE));
        Log.d("MediaMetadataRetriever", "音声を含むか:" + mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_AUDIO));
        Log.d("MediaMetadataRetriever", "動画を含むか:" + mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO));
        Log.d("MediaMetadataRetriever", "位置情報:" + mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_LOCATION));
        Log.d("MediaMetadataRetriever", "マイムタイプ:" + mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_MIMETYPE));
        Log.d("MediaMetadataRetriever", "オーディオ/ビデオ/テキストのトラック数:" + mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS));
        Log.d("MediaMetadataRetriever", "タイトル:" + mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE));
        Log.d("MediaMetadataRetriever", "ビデオの高さ:" + mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT));
        Log.d("MediaMetadataRetriever", "ビデオの回転角度:" + mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION));
        Log.d("MediaMetadataRetriever", "ビデオの幅:" + mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH));
        Log.d("MediaMetadataRetriever", "作家:" + mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_WRITER));
        Log.d("MediaMetadataRetriever", "作成年:" + mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_YEAR));

        /**
        * 指定した時間(us)の画像(Bitmap)を動画からキャプチャすることができます。
        * MediaMetadataRetriever#getFrameAtTimeを使います。
        * このメソッドは複数のオーバーロードがあります。
        * 今回は時間とオプションを設定するメソッドを使います。
        *
        * OPTION_CLOSEST→指定した時間に一番近いフレームを取得する。
        * OPTION_CLOSEST_SYNC→指定した時間に一番近い同期フレームを取得する。
        * OPTION_NEXT_SYNC→指定した時間の後の同期フレームを取得する。
        * OPTION_PREVIOUS_SYNC→指定した時間の前の同期フレームを取得する。
        *
        * 注意としては動画の高さ幅の画像を取得するのでメモリと処理時間がかかります。
        *
        */
        int count = Integer.parseInt(mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)) / 1000;
        bitmapArrayList = new ArrayList<>();
        for(int i = 0 ; i < count ; i++) {
            bitmapArrayList.add(mediaMetadataRetriever.getFrameAtTime(i * 1000 * 1000, MediaMetadataRetriever.OPTION_CLOSEST));
        }
        ImageViewAdapter imageViewAdapter = new ImageViewAdapter(getApplicationContext() , bitmapArrayList);
        gridView.setAdapter(imageViewAdapter);

        /**
        * 使ったファイルを開放する。
        */
        mediaMetadataRetriever.release();
    }
        
    class ImageViewAdapter extends ArrayAdapter<Bitmap> {
        public ImageViewAdapter(Context context, List<Bitmap> objects) {
            super(context, 0, objects);
        }
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if(convertView == null) {
                convertView = new ImageView(getContext());
                convertView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT , ViewGroup.LayoutParams.WRAP_CONTENT));
            }
            ImageView imageView = (ImageView) convertView;
            imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
            imageView.setImageBitmap(getItem(position));
            return convertView;
        }
    }
}

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)