トランスコーディング(Transcoding)とは、デジタルメディアファイルをある圧縮形式から別の形式に、完全なデコードと再エンコードを伴って変換するプロセスです。トランスマルチプレクシング(コンテナのみの変更)とは異なり、トランスコーディングはコーデック、ビットレート、解像度、その他の圧縮ストリームのパラメータを変更します。Apple AVFoundation documentation (2026) によると、トランスコーディングは異なるデバイスやネットワーク条件にコンテンツを適応させるために使用されます。
重要ポイント
トランスコーディングとは、メディアファイルをある圧縮形式から別の形式に変換するプロセスであり、ソースストリームを中間的な非圧縮PCM形式に完全にデコードし、新しいパラメータでエンコードします。ソースファイルが10 MbpsのビットレートでH.264コーデックを使用し、出力に3 MbpsのビットレートでH.265が必要な場合 — これがトランスコーディングです。
トランスコーディングは、単純な再パッケージング(トランスマルチプレクシング)とは異なります。トランスマルチプレクシングではコンテナのみが変更され(例:MP4からMKV)、圧縮ビットストリームは変更されません。トランスコーディングには計算コストの高い操作が含まれます:各フレームのデコード、フィルターの適用(スケーリング、色補正、クロッピング)、新しいパラメータでの再エンコードです。これにより、トランスコーディングはメディアを扱う際に最もリソースを消費する操作の1つになります。
トランスコーディングは幅広いタスクで使用されます:帯域幅制限に合わせたビデオの適応、ターゲットデバイスでのハードウェアデコード対応形式への変換、HLS/DASHストリーミング用の複数バージョン作成、オーディオトラックの別ファイルへの抽出。OTTサービス(Netflix、YouTube、Twitch)は、アップロードされた各ファイルを異なるビットレート、解像度、コーデックの数十のバリエーションにトランスコードし、何百万ものユーザーにアダプティブストリーミングを提供します。
トランスコーディングプロセスは、デコード、処理、エンコードの3つの主要な段階で構成されます。各段階は、可用性と必要なパフォーマンスに応じて、CPUまたはGPU/ハードウェアブロックで実行できます。
最初の段階は、ソースストリームのデコードです。ソースファイルはコンテナ(MP4、MOV、MKV)から読み取られ、圧縮されたビデオパケットがデコーダーに送信されます。デコードは、ハードウェアベース(コーデックがサポートされている場合)またはFFmpegを介したソフトウェアベースのいずれかです。デコードの出力は、YUV420またはBGRA形式の非圧縮フレームです — これがトランスコーディングが単純な再多重化と異なる段階です。
2番目の段階は、フィルタリングと処理です。デコードされたフレームは、フィルタのチェーンを通過します:ターゲット解像度へのスケーリング、フレームレートの変更、色補正、テキストやグラフィックのオーバーレイ。FFmpegフィルターチェーンはグラフとして構築され、各フィルターは個別の処理モジュールです。たとえば、scale=1280:720フィルターは解像度を変更し、fps=30はフレームレートを変更し、yadifはインターレース解除を行います。すべての操作は非圧縮フレームに対して実行されるため、2番目の段階が最もリソースを消費します。
3番目の段階は、ターゲット形式へのエンコードです。処理されたフレームはエンコーダーに送られ、ターゲットコーデックアルゴリズムに従って圧縮されます。エンコーダーは、ハードウェアベース(iOSのVideoToolbox、AndroidのMediaCodec)またはソフトウェアベース(libx264、libx265)です。エンコーディングパラメータ:一定品質のためのCRF(Constant Rate Factor)、CBR/VBRのためのビットレート、ターゲットデバイスとの互換性のためのプロファイルとレベル。
// FFmpegのトランスコーディングパイプライン図
AVFormatContext *inputCtx, *outputCtx;
AVCodecContext *decoderCtx, *encoderCtx;
AVFrame *frame = av_frame_alloc();
AVPacket packet;
while (av_read_frame(inputCtx, &packet) >= 0) {
// 1. デコード
avcodec_send_packet(decoderCtx, &packet);
avcodec_receive_frame(decoderCtx, frame);
// 2. フィルター(スケール+fps変更)
sws_scale(swsCtx, frame->data, frame->linesize,
0, frame->height, scaledFrame->data,
scaledFrame->linesize);
// 3. エンコード
avcodec_send_frame(encoderCtx, scaledFrame);
avcodec_receive_packet(encoderCtx, &outPacket);
av_interleaved_write_frame(outputCtx, &outPacket);
}
上記のパイプラインは、古典的なトランスコーディングサイクルを示しています。av_read_frame関数は入力ファイルから圧縮パケットを読み取り、avcodec_send_packetはそれらをフレームにデコードし、sws_scaleはスケーリングを実行し、avcodec_send_frameは処理されたフレームを出力形式にエンコードします。この3段階サイクルは、エンコーダー設定に応じて、各フレームまたはフレームグループ(GOP)ごとに繰り返されます。
トランスコーディングとトランスマルチプレクシングの違いは、メディアエンジニアリングで最もよくある混乱点の1つです。この違いを理解することは、適切なメディア処理戦略を選択するために重要です。
| パラメータ | トランスコーディング | トランスマルチプレクシング |
|---|---|---|
| 変更されるもの | コーデック、ビットレート、解像度 | コンテナ、メタデータ |
| 計算負荷 | 高い(デコード+エンコード) | 最小限(パケットコピー) |
| 品質 | 劣化する可能性あり(ジェネレーションロス) | ロスレス |
| 実行時間 | 長い動画で数分~数時間 | 数秒~数分 |
| 用途 | 形式適応、圧縮 | 互換性のためのコンテナ変更 |
トランスマルチプレクシングは、デコードや再エンコードを行わずに、圧縮ストリームを別のコンテナに再パッケージングすることです。動画がすでにMP4コンテナ内でH.265コーデックで圧縮されており、MOVまたはMKVコンテナに配置する必要がある場合 — トランスマルチプレクシングは単にビットストリームパケットをあるコンテナから別のコンテナにコピーします。品質は影響を受けず、フレームデコードが不要なため処理時間は最小限です。FFmpegは-codec copyフラグでトランスマルチプレクシングを実行します。
トランスコーディングは、一方で、メディアストリームを完全にデコードして再圧縮します。動画がトランスコーディングを通過するたびに、ジェネレーションロス(世代損失)が発生する可能性があります — 損失のある圧縮を繰り返すことによる品質のわずかな低下です。同じビットレートでも、トランスコーディングの3世代目は通常1世代目よりも品質が低下します。そのため、プロフェッショナルはマスターコピーを非圧縮または最小限の圧縮形式(ProRes、DNxHR)で保存し、配信用の最終バージョンのみをトランスコードすることを推奨しています。
トランスコーディングツールの選択は、プラットフォーム、パフォーマンス要件、およびユースケースによって異なります。モバイル開発では、ネイティブAPIとクロスプラットフォームライブラリの両方が利用可能です。
FFmpegは、すべてのプラットフォームにおけるトランスコーディングのデファクトスタンダードです。FFmpegコマンドラインを使用すると、コーデック変更、ビットレート調整、トリミング、連結、フィルター適用など、事実上すべての変換を実行できます。モバイルアプリケーションの場合、FFmpegはlibavformat、libavcodec、libavfilterライブラリを介して統合されます。典型的なトランスコーディングコマンドの例:ffmpeg -i input.mp4 -c:v libx265 -crf 23 -c:a aac -b:a 128k output.mp4。
iOSでは、トランスコーディングはAVAssetWriterとAVAssetReaderを介して実行されます。AVAssetReaderは非圧縮フレームを読み取ってソースファイルをデコードし、AVAssetWriterはそれらをターゲット形式にエンコードします。このアプローチは自動的にVideoToolboxハードウェアエンコーダーを使用し、最大のパフォーマンスを保証します。Androidでは、同様の機能がMediaCodecをMediaExtractorおよびMediaMuxerと組み合わせて利用可能です — MediaExtractorは圧縮パケットを抽出し、MediaCodecはデコードとエンコードを行い、MediaMuxerは結果を書き込みます。
本番環境でのサーバーサイドトランスコーディングには、クラウドサービスが使用されます:AWS Elemental MediaConvert、Azure Media Services、Google Transcoder API。これらのサービスは負荷に応じて自動的にスケールし、すべての人気形式をサポートし、アダプティブストリーミング(HLS、DASH)用に単一の入力ファイルを数十の出力バリエーションにトランスコードできます。モバイルアプリケーションの場合、クラウドトランスコーディングはユーザーのデバイスに負荷をかけず、非同期のコンテンツ準備を可能にするため、最適なソリューションです。
ハードウェアアクセラレーションと主要な品質パラメータ設定を使用した、モバイルプラットフォームでの実際のトランスコーディング例を見てみましょう。
import AVFoundation
func transcodeVideo(sourceURL: URL, destURL: URL) {
let asset = AVAsset(url: sourceURL)
let preset = AVAssetExportPresetHEVCHighestQuality
AVAssetExportSession(asset: asset, presetName: preset)?
.exportAsynchronously {
switch assetExportSession?.status {
case .completed:
print("トランスコーディング完了")
case .failed:
print("エラー: " + assetExportSession.error.localizedDescription)
default:
break
}
}
// AVAssetReader + AVAssetWriterによる手動トランスコーディング
let reader = try AVAssetReader(asset: asset)
let writer = try AVAssetWriter(url: destURL,
fileType: .mp4)
let outputSettings: [String: Any] = [
AVVideoCodecKey: AVVideoCodecType.hevc,
AVVideoWidthKey: 1920,
AVVideoHeightKey: 1080,
AVVideoCompressionPropertiesKey: [
AVVideoAverageBitRateKey: 4_000_000,
AVVideoProfileLevelKey: AVVideoProfileLevelH265Main10
]
]
let adaptor = AVAssetWriterInput(
mediaType: .video,
outputSettings: outputSettings
)
writer.add(adaptor)
}
この例は、iOSでのトランスコーディングの2つのアプローチを示しています。AVAssetExportSessionは、品質プリセット(H.265用のHEVCHighestQuality)を使用した簡単な方法です。AVAssetReader + AVAssetWriterによる手動パイプラインは、ビットレート、プロファイル、レベルなどのパラメータを完全に制御できます。AVVideoProfileLevelH265Main10パラメータは、10ビット色深度のHDRプロファイルMain10を有効にします。これは最新のHDRコンテンツにとって重要です。
class Transcoder(private val context: Context) {
fun transcodeToHevc(inputUri: Uri, outputFile: File) {
val extractor = MediaExtractor()
extractor.setDataSource(context, inputUri, null)
val trackFormat = extractor.getTrackFormat(videoTrackIndex)
val mime = trackFormat.getString(MediaFormat.KEY_MIME)
val decoder = MediaCodec.createDecoderByType(mime!!)
val encoder = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_VIDEO_HEVC)
val outputFormat = MediaFormat.createVideoFormat(
MediaFormat.MIMETYPE_VIDEO_HEVC, 1920, 1080
).apply {
setInteger(MediaFormat.KEY_BIT_RATE, 4_000_000)
setInteger(MediaFormat.KEY_FRAME_RATE, 30)
setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 2)
}
encoder.configure(outputFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE)
encoder.start()
}
}
Androidのコードは、MediaExtractor — MediaCodecデコーダー — MediaCodecエンコーダー — MediaMuxerのパイプラインを作成します。MediaExtractorは入力ファイルからコーデックタイプを判別し、対応するデコーダーを選択します。エンコーダーはH.265(HEVC)用に4 Mbpsのビットレートと2秒のキーフレーム間隔で設定され、ストリーミングに最適です。重要:MediaCodecエンコーダーは同期的に動作するため、リアルタイムトランスコーディングには各フレームの正しいPTSタイムスタンプ処理を備えたループを実装する必要があります。
モバイルデバイスでのトランスコーディングは、限られたCPU、GPUリソースと熱的制約のために注意深い最適化を必要とするタスクです。いくつかの戦略が効率的なトランスコーディングを可能にします。
主要なパフォーマンス要因はハードウェアエンコーダーです。iOSでは、VideoToolboxがソフトウェアlibx264よりも5〜10倍高速なハードウェアH.264およびH.265エンコーディングを提供します。Androidでは、MediaCodecは利用可能な場合にハードウェアOMXコンポーネントを使用します。ハードウェアエンコーディングを有効にすると、フラッグシップデバイスで10分の動画のトランスコーディング時間が30〜40分(ソフトウェア)から3〜5分(ハードウェア)に短縮されます。
モバイルトランスコーディングでは、品質、サイズ、処理時間のバランスが重要です。モバイルデバイスでのH.265の場合、30 FPSの1080p動画には4〜8 Mbpsのビットレートが推奨されます。libx265のCRFモード(Constant Rate Factor)では品質を直接設定でき、23〜28は適度なファイルサイズで良好な視覚品質を提供します。ハードウェアエンコーダーの場合、CRFはハードウェアでサポートされていないため、ターゲットビットレートでCBRモードを使用します。
モバイルデバイスでの継続的なトランスコーディングは、著しい発熱を引き起こします。4K動画の5〜7分間の集中的なエンコーディング後、プロセッサ温度は50〜55度に達し、その後スロットリングが作動します。解決策は、休止を入れてトランスコードするか、フレームレートを30 FPSに下げることです。アプリケーションがバッチトランスコーディングを必要とする場合(例:ビデオエディター)、冷却間隔を挟んで2〜3分のバッチで処理するのが最適です。本番シナリオでは、トランスコーディングをサーバーサイドにオフロードし、クラウドサービスを使用することが最適です。
よくある質問
エンコーディングは、生の非圧縮データをターゲットコーデックに圧縮することです。トランスコーディングはデコードとエンコードの両方を含みます:最初に既存の圧縮ストリームをデコードし、次に再度エンコードします。単純なエンコーディングは入力として非圧縮データ(例:カメラからのデータ)を受け取りますが、トランスコーディングはすでに圧縮されたファイルを受け取ります。
最大の互換性には — H.264。より良い圧縮には — H.265(HEVC)。デバイスがハードウェアH.265エンコーディングをサポートしている場合(iPhone 8+、Snapdragon 845+搭載Android)、同じ品質でファイルサイズは半分になります。AV1エンコーディングはモバイルデバイスではハードウェアアクセラレーションがあってもまだ遅すぎます。
厳密に言えば、非可逆コーデック間でのロスレストランスコーディングは不可能です。両方のコーデックが非可逆の場合、トランスコーディングの世代を重ねるごとに品質が低下します。ロスレストランスコーディングは、ロスレス形式間(FFV1、H.264 Lossless)または再エンコードなしのコンテナ変更(トランスマルチプレクシング)でのみ可能です。
はい、ハードウェアデコーダーとエンコーダーを使用し、ターゲット解像度が1080pを超えない場合に可能です。VideoToolbox(iOS)またはMediaCodec(Android)を搭載したデバイスでは、1〜3秒の遅延でリアルタイムH.264→H.265トランスコーディングが可能です。4Kリアルタイムには、Apple A17 Pro、Snapdragon 8 Gen 2以上の強力なSoCが必要です。
非可逆トランスコーディングは圧縮アーティファクトを蓄積します。ソースファイルがすでに強く圧縮されていた場合(1080pで2〜3 Mbpsのビットレート)、再圧縮により損失が2倍になります。推奨されるのは、高ビットレート(20+ Mbps)のマスターコピーからのみトランスコードし、最小限の損失のためにCRF 18〜23を使用することです。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。