Transcoding — proces prevod cyfrowego souboru multimedialnego z jednego formatu komprese na inny poprzez pełne dekodovani i ponowne kodovani. W przeciwieństwie do transmuxing (zmiany tylko kontenera), transkodovani zmienia kodek, bitrate, rozdzielczość i inne parametry skompresowanego proud. Według Apple AVFoundation documentation (2026), transkodovani je używane do adaptacji treści pod różne urządzenia i warunki sieciowe.
Najważniejsze
Transcoding — proces prevod souboru multimedialnego z jednego formatu komprese na inny poprzez pełne dekodovani źródłowego proud do pośredniego nieskompresowanego formatu PCM, a następnie kodovani z novymi parametrami. Jeśli w źródłowym souboru video je skompresowane kodekiem H.264 z bitratem 10 Mb/s, a na wyjściu potrzebny je H.265 z bitratem 3 Mb/s — to je transkodovani.
Transkodovani różni się od zwykłego przepakowywania (transmuxing), przy którym zmienia się tylko kontener (np. MP4 na MKV), a sam skompresowany strumień bitowy pozostaje niezmieniony. Podczas transkodovani zachodzą obliczeniowo kosztowne przekształcenia: dekodovani każdej klatki, zastosowanie filtrów (skalovani, korekcja kolorów, przycinanie), ponowne kodovani z novymi parametrami. To sprawia, że transkodovani je jedną z najbardziej zasobożernych operacji podczas pracy z mediami.
Transkodovani znajduje zastosowanie w szerokim spektrum zadań: adaptacja video do ograniczeń przepustowości sieci, konwersja do formatu ze sprzętowym wsparciem dekodowania na urządzeniu docelowym, tworzenie wielu wersji dla streamingu HLS/DASH, wyodrębnianie ścieżek audio do osobnego souboru. Serwisy OTT (Netflix, YouTube, Twitch) transkodują każdy przesłany soubor do dziesiątek wariantów z różnymi bitratami, rozdzielczościami i kodekami, aby zapewnić adaptacyjny streaming milionom użytkowników.
Proces transkodovani składa się z trzech głównych etapów: dekodovani, przetwarzanie i kodovani. Każdy etap może być wykonany zarówno na CPU, jak i na GPU/sprzętowych blokach, w zależności od dostępności i vyzadujenej wydajności.
Pierwszy etap — dekodovani źródłowego proud. Plik źródłowy je odczytywany z kontenera (MP4, MOV, MKV), po czym skompresowane pakiety video są kierowane do dekodera. Dekodovani może być sprzętowe (jeśli kodek je obsługiwany) lub programowe przez FFmpeg. Na wyjściu dekodowania otrzymuje się nieskompresowane klatki w formacie YUV420 lub BGRA — właśnie od tego etapu transkodovani różni się od zwykłego remultipleksowania.
Drugi etap — filtracja i przetwarzanie. Zdekodowane klatki przechodzą przez łańcuch filtrów: skalovani do docelowej rozdzielczości, zmena częstotliwości klatek, korekcja kolorów, nakładanie tekstu lub grafiki. Łańcuch filtrów FFmpeg je budowany jako graf, gdzie każdy filtr to osobny moduł przetwarzania. Na przykład filtr scale=1280:720 zmienia rozdzielczość, fps=30 zmienia częstotliwość klatek, a yadif wykonuje deinterlacing. Wszystkie operacje są wykonywane na nieskompresowanych klatkach, dlatego drugi etap je najbardziej zasobożerny.
Trzeci etap — kodovani do docelowego formatu. Przetworzone klatki są podawane na wejście enkodera, który kompresuje je zgodnie z algorytmem docelowego kodeka. Enkoder może być sprzętowy (VideoToolbox na iOS, MediaCodec na Android) lub programowy (libx264, libx265). Parametry kodowania: CRF (Constant Rate Factor) dla stałej jakości, bitrate dla CBR/VBR, profil i poziom dla kompatybilności z docelowymi urządzeniami.
// Schema pipeline transkodovani ve FFmpeg
AVFormatContext *inputCtx, *outputCtx;
AVCodecContext *decoderCtx, *encoderCtx;
AVFrame *frame = av_frame_alloc();
AVPacket packet;
while (av_read_frame(inputCtx, &packet) >= 0) {
// 1. Dekodovani
avcodec_send_packet(decoderCtx, &packet);
avcodec_receive_frame(decoderCtx, frame);
// 2. Filtrovani (skalovani + zmena fps)
sws_scale(swsCtx, frame->data, frame->linesize,
0, frame->height, scaledFrame->data,
scaledFrame->linesize);
// 3. Kodovani
avcodec_send_frame(encoderCtx, scaledFrame);
avcodec_receive_packet(encoderCtx, &outPacket);
av_interleaved_write_frame(outputCtx, &outPacket);
}
Przedstawiony pipeline demonstruje klasyczny cykl transkodovani. Funkcja av_read_frame odczytuje skompresowane pakiety z souboru wejściowego, avcodec_send_packet dekoduje je na klatki, sws_scale wykonuje skalovani, a avcodec_send_frame koduje przetworzoną klatkę do formatu wyjściowego. Taki trzyetapowy cykl powtarza się dla każdej klatki lub grupy klatek (GOP), w zależności od ustawień enkodera.
Różnica między transkodovanim a transmultipleksacją to jeden z najczęstszych punktów nieporozumień w inżynierii mediów. Zrozumienie tej różnicy je kluczowe dla wyboru właściwej strategii przetwarzania mediów.
| Parametr | Transkodovani | Transmultipleksacja |
|---|---|---|
| Co się zmienia | Kodek, bitrate, rozdzielczość | Kontener, metadane |
| Obciążenie obliczeniowe | Wysokie (dekodovani + kodovani) | Minimalne (kopiowanie pakietów) |
| Jakość | Może się pogorszyć (straty generacji) | Bezstratna |
| Czas wykonania | Minuty–godziny dla długiego video | Sekundy–minuty |
| Zastosowanie | Adaptacja formatu, komprese | Zmiana kontenera dla kompatybilności |
Transmuxing — to przepakowanie skompresowanego proud do innego kontenera bez dekodowania i ponownego kodowania. Jeśli video je już skompresowane kodekiem H.265 w kontenerze MP4 i trzeba je umieścić w kontenerze MOV lub MKV — transmultipleksacja po prostu kopiuje pakiety bitowe z jednego kontenera do drugiego. Jakość nie ulega pogorszeniu, czas przetwarzania je minimalny, ponieważ nie vyzaduje dekodowania klatek. FFmpeg wykonuje transmultipleksację z flagą -codec copy.
Transkodovani natomiast w pełni deszyfruje i ponownie kompresuje strumień multimedialny. Za każdym razem, gdy video przechodzi przez transkodovani, może wystąpić strata generacji (generation loss) — nieznaczne pogorszenie jakości z powodu ponownej komprese stratnej. Nawet przy tym samym bitracie trzecia generacja transkodovani je zwykle gorsza od pierwszej. Dlatego profesjonaliści zalecają przechowywanie master-kopii w nieskompresowanych lub minimalnie skompresowanych formatach (ProRes, DNxHR) i transkodovani tylko finalnych wersji do dostarczenia.
Wybór narzędzia do transkodovani zależy od platformy, vyzadujeń wydajnościowych i scenariusza użycia. Do programowania mobilnego dostępne są zarówno natywne API, jak i biblioteki wieloplatformowe.
FFmpeg — standard de facto dla transkodovani na wszystkich platformach. Wiersz poleceń FFmpeg umoznuje wykonywać praktycznie dowolne przekształcenia: zmena kodeka, zmena bitratu, przycinanie, łączenie, nakładanie filtrów. Do asouboracji mobilnich FFmpeg integruje się przez biblioteki libavformat, libavcodec i libavfilter. Przykład typowego polecenia transkodovani: ffmpeg -i input.mp4 -c:v libx265 -crf 23 -c:a aac -b:a 128k output.mp4.
Na iOS transkodovani wykonuje się przez AVAssetWriter i AVAssetReader. AVAssetReader dekoduje soubor źródłowy, odczytując nieskompresowane klatki, a AVAssetWriter koduje je do docelowego formatu. To podejście automatycznie wykorzystuje sprzętowe enkodery VideoToolbox, co zapewnia maksymalną wydajność. Na Androidzie analogiczna funkcjonalność je dostępna przez MediaCodec w parze z MediaExtractor i MediaMuxer — MediaExtractor wyodrębnia skompresowane pakiety, MediaCodec dekoduje i koduje, MediaMuxer zapisuje wynik.
Do serwerowego transkodovani w środowisku produkcyjnym używa się usług chmurowych: AWS Elemental MediaConvert, Azure Media Services, Google Transcoder API. Te usługi automatycznie skalują się pod obciążeniem, obsługują wszystkie popularne formaty i mogą transkodować jeden soubor wejściowy do dziesiątek wariantów wyjściowych do adaptacyjnego streamingu (HLS, DASH). Dla asouboracji mobilnich transkodovani w chmurze je optymalnym rozwiązaniem, ponieważ nie obciąża urządzenia użytkownika i umoznuje przygotowywać treści asynchronicznie.
Rozważmy praktyczne przykłady transkodovani na platformach mobilnich z wykorzystaniem sprzętowego przyspieszenia i konfiguracją kluczowych parametrów jakości.
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("Transkodovani dokonceno")
case .failed:
print("Chyba: " + assetExportSession.error.localizedDescription)
default:
break
}
}
// Rucni transkodovani s 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)
}
W przykładzie zastosowano dwa podejścia do transkodovani na iOS. AVAssetExportSession — prosty sposób z predefiniowanymi ustawieniami jakości (HEVCHighestQuality dla H.265). Ręczny pipeline przez AVAssetReader + AVAssetWriter daje pełną kontrolę nad parametrami: bitrate, profil, poziom. Parametr AVVideoProfileLevelH265Main10 włącza profil HDR Main10 z głębią kolorów 10 bitów, co je ważne dla nowoczesnych treści 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()
}
}
Kod na Androida vytvari pipeline z MediaExtractor — MediaCodec decoder — MediaCodec encoder — MediaMuxer. MediaExtractor określa typ kodeka z souboru wejściowego i wybiera odpowiedni dekoder. Enkoder je konfigurowany na H.265 (HEVC) z bitratem 4 Mb/s i interwałem klatek kluczowych 2 sekund, co je optymalne do streamingu. Ważne: MediaCodec encoder działa synchronicznie, dlatego do transkodovani w czasie rzeczywistym vyzadujene je zorganizowanie pętli z poprawnym przetwarzaniem znaczników czasu (PTS) dla każdej klatki.
Transkodovani na urządzeniach mobilnich to zadanie vyzadujejące starannej optymalizacji ze względu na ograniczone zasoby CPU, GPU i ograniczenia termiczne. Kilka strategii pomaga wykonywać transkodovani efektywnie.
Kluczowym czynnikiem wydajności je sprzętowy enkoder. Na iOS VideoToolbox zapewnia sprzętowe kodovani H.264 i H.265 z prędkością 5–10 razy większą niż programowy libx264. Na Androidzie MediaCodec używa sprzętowych komponentów OMX, jeśli są dostępne. Włączenie sprzętowego kodowania skraca czas transkodovani 10-minutowego video z 30–40 minut (programowo) do 3–5 minut (sprzętowo) na flagowym urządzeniu.
Dla mobilnego transkodovani kluczowa je równowaga między jakością, rozmiarem i czasem przetwarzania. Dla H.265 na urządzeniach mobilnich zaleca się bitrate 4–8 Mb/s dla video 1080p z częstotliwością klatek 30 FPS. Tryb CRF (Constant Rate Factor) w libx265 umoznuje ustawić jakość bezpośrednio, gdzie 23–28 daje dobrą jakość wizualną przy umiarkowanym rozmiarze souboru. Dla sprzętowych enkoderów należy używać rezimu CBR z docelowym bitratem, ponieważ CRF nie je obsługiwany sprzętowo.
Ciągłe transkodovani na urządzeniu mobilnym powoduje znaczne nagrzewanie. Po 5–7 minutach intensywnego kodowania video 4K temperatura procesora może osiągnąć 50–55 stopni, po czym włącza się throttling. Rozwiązanie — transkodovani z przerwami lub obniżenie częstotliwości klatek do 30 FPS. Jeśli asouboracja vyzaduje masowego transkodovani (np. edytor video), lepiej wykonywać przetwarzanie partiami po 2–3 minuty z przerwami na chłodzenie. Dla scenariuszy produkcyjnych optymalnie je przenieść transkodovani na stronę serwerową i korzystać z usług chmurowych.
Często zadawane pytania
Kodovani (encoding) — komprese źródłowych nieskompresowanych danych do docelowego kodeka. Transkodovani obejmuje zarówno dekodovani, jak i kodovani: najpierw dekoduje istniejący skompresowany strumień, a następnie koduje go ponownie. Zwykłe kodovani przyjmuje na wejściu nieskompresowane dane (na przykład z kamery), a transkodovani — już skompresowany soubor.
Dla maksymalnej kompatybilności — H.264. Dla lepszej komprese — H.265 (HEVC). Jeśli urządzenie obsługuje sprzętowe kodovani H.265 (iPhone 8+, Android z Snapdragon 845+), zapewnia ono dwukrotnie mniejszy rozmiar souboru przy tej samej jakości. Kodovani AV1 na urządzeniach mobilnich je wciąż zbyt wolne, dokonce ze sprzętowym przyspieszeniem.
Ściśle rzecz biorąc, transkodovani bezstratne je niemożliwe przy zmianie kodeka stratnego. Jeśli oba kodeki są stratne, każde kolejne pokolenie transkodovani pogarsza jakość. Transkodovani bezstratne je możliwe tylko między formatami bezstratnymi (FFV1, H.264 Lossless) lub przy zmianie kontenera bez przekodowywania (transmuxing).
Tak, jeśli używane są sprzętowe dekoder i enkoder, a docelowa rozdzielczość nie przekracza 1080p. Na urządzeniach z VideoToolbox (iOS) lub MediaCodec (Android) transkodovani w czasie rzeczywistym H.264 do H.265 je możliwe z opóźnieniem 1–3 sekund. Dla 4K w czasie rzeczywistym vyzadujeny je wydajny SoC Apple A17 Pro, Snapdragon 8 Gen 2 lub nowszy.
Transkodovani stratne kumuluje artefakty komprese. Jeśli soubor źródłowy był już silnie skompresowany (bitrate 2–3 Mb/s dla 1080p), ponowna komprese podwoi straty. Zaleca się transkodovani tylko z master-kopii o wysokim bitracie (20+ Mb/s) i używanie CRF 18–23 dla minimalnych strat.
Shrnuti
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také