この記事は Android スマホ用のアプリ開発の中で、
今後の開発で再使用性が高いと思われるコーディングをまとめたものです。
Java での開発経験、XML 構文規則、Android のアプリ開発経験がある方を対象としています。
Android のアプリ開発でお役にたててれば、嬉しいです。
(これから Android のアプリ開発や Java での開発を始めたい方への案内は、記事の最後で紹介します)
Androidのスマホは、MP4形式しか動画ファイルは再生できません。
ビデオカメラで撮影した動画ファイルは、MTS形式が多い。
MTS形式の動画ファイルをAndroidで再生するには、MP4形式に変換する必要があります。
Android13から、AIFF形式(Apple標準のオーディオ形式)の音楽ファイルが再生できなくなっています。
CDの曲をiTunesに取り込んだ音楽ファイルをAndroid13以降で再生するには、MP3形式に変換する必要があります。
FFmpegは、動画ファイルや音声ファイルを記録・変換・再生するためのフリーソフトウェアです。
Androidで対応していない形式のファイルはFFmpegを使用して、MP4形式やMP3形式に変換すれば、Androidでも再生できるようになります。
FFmpegKitは、Androidで使用できるオープンソフトウェアライブラリです。
ffmpegkitを使用するための準備
ffmpegkitを使用するには、
プロジェクトおよび、モジュールのbuild.gradleファイルに定義の追加が必要です。
◎build.gradle(プロジェクト)
:
allprojects {
repositories {
mavenCentral()
:
}
}
:
◎build.gradle(モジュール)
2024年2月現在の最新バージョンは 6.0.2 です。
dependencies {
:
implementation 'com.arthenica:ffmpeg-kit-full:6.0-2'
}
◎ライセンス表記
ffmpegkitは、LGPL v3.0 Licenseです。
アプリで使用する場合、ライセンス表記が必要です。
動画ファイルの形式を変換する
ffmpegkitは、コマンドライン引数で動画ファイルの変換動作をパラメータで指定します。
フォーマット、コーデック、開始位置や長さ、品質指定などが指定できます。
これらパラメータ指定の組み合わせで、MP4形式変換、サムネイルの作成、動画のトリミングが可能です。
メディアストア(動画フォルダ)の動画ファイルにアクセスするには、きめ細かいメディア権限を設定する必要があります。
詳細は、Android13対応(ファイルのメディア権限)で紹介しています。
MP4形式変換
FFmpegKitは、動画ファイルの形式は拡張子で判断しています。
入力ファイルがMP4形式以外の拡張子で、出力ファイルの拡張子がMP4形式であれば、MP4形式に変換できます。
import com.arthenica.ffmpegkit.FFmpegKit;
import com.arthenica.ffmpegkit.FFmpegKitConfig;
import com.arthenica.ffmpegkit.FFmpegSession;
import com.arthenica.ffmpegkit.ReturnCode;
:
String[] mimeList = new String[]{"video/mp4", "video/webm", "video/quicktime", "video/mp2ts"};
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(() -> {
try {
ContentResolver resolver = context.getContentResolver();
Cursor cursor = resolver.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, null, null, null, "_ID DESC");
while (cursor.moveToNext()) {
if (Arrays.asList(mimeList).contains(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.MIME_TYPE)))) {
Uri contentUri = ContentUris.withAppendedId(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, Long.parseLong(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID))));
String path = cursor.getString(cursor.getColumnIndex(MediaStore.Video.VideoColumns.DATA));
String source = cursor.getString(cursor.getColumnIndex(MediaStore.Video.VideoColumns.DISPLAY_NAME));
String ext = source.substring(source.lastIndexOf(".")).toLowerCase();
long width = Long.parseLong(cursor.getString(cursor.getColumnIndex(MediaStore.Video.VideoColumns.WIDTH)));
long height = Long.parseLong(cursor.getString(cursor.getColumnIndex(MediaStore.Video.VideoColumns.HEIGHT)));
// 拡張子がMP4以外はコーディック
if (!ext.equals(".mp4") && ext.length() > 0) {
// ファイル名からスペース削除と拡張子変更
String file = source.toLowerCase().replace(" ", "").replace(" ", "").replace(ext, ".mp4");
path = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES) + File.separator + file;
// mp4ファイル変換
String mts = FFmpegKitConfig.getSafParameterForRead(context, contentUri);
String mp4 = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES) + File.separator + file;
FFmpegSession session = FFmpegKit.execute(String.format("-i '%s' -qmin %d -qmax %d -acodec libmp3lame -ab 192000 -ar 48000 -s %dx%d '%s'", mts, 16, 20, width ,height , mp4));
if (ReturnCode.isSuccess(session.getReturnCode())) {
// 変換成功
:
} else {
// 変換失敗
:
}
}
}
}
cursor.close();
} catch (Exception e) {
e.printStackTrace();
}
});
コンテンツリゾルバを使用して、メディアストア(動画フォルダ)の動画ファイルのリストを取得しています。
また、MIMEタイプがmp4、webm、quicktime(MOV)、mp2ts(MTS)の動画ファイルか判定しています。
コンテンツリゾルバのクエリ結果より、Uri、パス、ファイル名、拡張子、サイズを取得します。
MP4形式以外の場合、MP4形式に変換します。
FFmpegKitの引数として、入力ファイルパス(-i)、品質指定(-qmin, -qmax)、音声コーディック(-acodec)、音声サンプリングレートレート(-ar)、音声ビットレート(-ab)、サイズ(-s 横*縦)、出力ファイルパスを指定しています。
動画コーディックは、デフォルト(指定なし)を使用します。
変換結果は、FFmpegSessionで判定します。
サムネイル画像の作成
動画ファイルの開始位置とフレーム数に1を指定することで、サムネイル画像ファイルを出力できます。
import com.arthenica.ffmpegkit.FFmpegKit;
:
String[] mimeList = new Strin