Видео и аудио кодирование
Перейти к навигации
Перейти к поиску
Главное, что нужно понять:
- Видеофайлы(медиафайлы) содержат потоки(дорожки): видеопоток, аудиопоток, субтитры и другую информацию(например видеорегистраторы авто - gps координаты и время).
- Потоки упакованы в контейнер: avi, mkv, mp4, wmv, mov...
- Потоки сжаты кодеками: h264, mpeg, mp3, aac, vp8, vp9, av1...
- Потоки можно извлекать и работать с ними отдельно. Добавлять сдвиги, удалять и пр. Зависит от контейнера и кодека.
- При кодировании важна производительность декодирования. Чтобы компьютер пользователя не грелся. Или ноутбук или телефон не разряжались. Есть аппаратная поддержка кодеков для этих целей. Выбирайте кодеки с аппаратной поддержкой, иначе видеофайл будет воспроизводится центральным процессором.
- Кодеки бывают свободные и несвободные(требуют уплаты роялти или платы за использование алгоритма)
Видео
Ссылки
- https://trac.ffmpeg.org/wiki/HWAccelIntro
- https://standaloneinstaller.com/blog/big-list-of-sample-videos-for-testers-124.html
- https://file-examples.com/index.php/sample-video-files/
Кодеки
$ mediainfo --Output=XML ./Terminator_Genezis.avi <?xml version="1.0" encoding="UTF-8"?> <Mediainfo version="0.1" ref="./Terminator_Genezis.avi"> <File> <track type="General"> <Complete_name>./Terminator_Genezis.avi</Complete_name> <Format>AVI</Format> <Format_Info>Audio Video Interleave</Format_Info> <File_size>1.46 GiB</File_size> <Duration>2h 5mn</Duration> <Overall_bit_rate>1 663 Kbps</Overall_bit_rate> <Writing_application>VirtualDubMod 1.5.10.3 | www.virtualdub-fr.org || (build 2550/release)</Writing_application> <Writing_library>VirtualDubMod build 2550/release</Writing_library> </track> <track type="Video"> <ID>0</ID> <Format>MPEG-4 Visual</Format> <Format_profile>Advanced Simple@L5</Format_profile> <Format_settings__BVOP>1</Format_settings__BVOP> <Format_settings__QPel>No</Format_settings__QPel> <Format_settings__GMC>No warppoints</Format_settings__GMC> <Format_settings__Matrix>Custom</Format_settings__Matrix> <Codec_ID>XVID</Codec_ID> <Codec_ID_Hint>XviD</Codec_ID_Hint> <Duration>2h 5mn</Duration> <Bit_rate>1 269 Kbps</Bit_rate> <Width>720 pixels</Width> <Height>304 pixels</Height> <Display_aspect_ratio>2.35:1</Display_aspect_ratio> <Frame_rate>23.976 (23976/1000) fps</Frame_rate> <Color_space>YUV</Color_space> <Chroma_subsampling>4:2:0</Chroma_subsampling> <Bit_depth>8 bits</Bit_depth> <Scan_type>Progressive</Scan_type> <Compression_mode>Lossy</Compression_mode> <Bits__Pixel_Frame_>0.242</Bits__Pixel_Frame_> <Stream_size>1.11 GiB (76%)</Stream_size> <Writing_library>XviD 73</Writing_library> </track> <track type="Audio"> <ID>1</ID> <Format>AC-3</Format> <Format_Info>Audio Coding 3</Format_Info> <Mode_extension>CM (complete main)</Mode_extension> <Format_settings__Endianness>Big</Format_settings__Endianness> <Codec_ID>2000</Codec_ID> <Duration>2h 5mn</Duration> <Bit_rate_mode>Constant</Bit_rate_mode> <Bit_rate>384 Kbps</Bit_rate> <Channel_s_>6 channels</Channel_s_> <Channel_positions>Front: L C R, Side: L R, LFE</Channel_positions> <Sampling_rate>48.0 KHz</Sampling_rate> <Frame_rate>31.250 fps (1536 spf)</Frame_rate> <Compression_mode>Lossy</Compression_mode> <Stream_size>345 MiB (23%)</Stream_size> <Alignment>Split accross interleaves</Alignment> <Interleave__duration>42 ms (1.00 video frame)</Interleave__duration> <Interleave__preload_duration>500 ms</Interleave__preload_duration> </track> </File> </Mediainfo>
H.264
function transform_video_x264_aac_mp4($file_src,$file_dst,$width,$height,$vb,$ab,$tmp_dir="./") { if (!file_exists($file_src)) return false; $X264_SUBQ="1"; $X264_FRAMEREF="1"; $X264_KEYINT="125"; $X264_THREADS="auto"; $X264_ME="hex"; $X264_BFRAMES="1"; $session_id=time(); $files_prefix = $tmp_dir."".$session_id; $mediainfo = $this->exec_program("mediainfo ".$file_src); preg_match("/General[\s\S]*?Format\s+\:\s+(.*)\s+/",$mediainfo,$m); $format = $m[1]; $format_profile = ""; if (preg_match("/General[\s\S]*?Format profile\s+\:\s+(.*)\s+/",$mediainfo,$m)) { $format_profile = $m[1]; } $format_info = ""; if (preg_match("/General[\s\S]*?Format\/Info\s+\:\s+(.*)\s+/",$mediainfo,$m)) { $format_info = $m[1]; } preg_match("/Video[\s\S]*?Frame rate\s+\:\s+(.*?)\s+fps/",$mediainfo,$m); //echo $format."\n"; $fps = $m[1]; if ($format_info == "Apple") { // dump audio $this->exec_program("mplayer -quiet ".$file_src." -ao pcm:fast:file=".$files_prefix."_audiostream -vc dummy -vo null -channels 2"); // encode video from src $this->exec_program("mencoder ".$file_src." -ovc x264 -x264encopts bitrate=".$vb.":subq=".$X264_SUBQ.":frameref=".$X264_FRAMEREF.":me=".$X264_ME.":bframes=".$X264_BFRAMES.":threads=".$X264_THREADS.":keyint=".$X264_KEYINT." -of rawvideo -vf scale=".$width.":".$height." -ofps ".$fps." -nosound -o ".$files_prefix."_videostream.x264"); // encode audio $this->exec_program("ffmpeg -i ".$files_prefix."_audiostream -strict experimental -acodec aac -ab ".$ab." -ac 2 ".$files_prefix."_audiostream.aac"); $this->exec_program("MP4Box -new -add ".$files_prefix."_videostream.x264 -fps ".$fps." -add ".$files_prefix."_audiostream.aac ".$file_dst.""); $this->exec_program("rm -f ".$files_prefix."_*"); return true; } if ($format_profile == "QuickTime") { // dump audio $this->exec_program("mplayer -quiet ".$file_src." -ao pcm:fast:file=".$files_prefix."_audiostream -vc dummy -vo null -channels 2"); // encode video from src $this->exec_program("mencoder ".$file_src." -ovc x264 -x264encopts bitrate=".$vb.":subq=".$X264_SUBQ.":frameref=".$X264_FRAMEREF.":me=".$X264_ME.":bframes=".$X264_BFRAMES.":threads=".$X264_THREADS.":keyint=".$X264_KEYINT." -of rawvideo -vf scale=".$width.":".$height." -ofps ".$fps." -nosound -o ".$files_prefix."_videostream.x264"); // encode audio $this->exec_program("ffmpeg -i ".$files_prefix."_audiostream -strict experimental -acodec aac -ab ".$ab." -ac 2 ".$files_prefix."_audiostream.aac"); $this->exec_program("MP4Box -new -add ".$files_prefix."_videostream.x264 -fps ".$fps." -add ".$files_prefix."_audiostream.aac ".$file_dst.""); $this->exec_program("rm -f ".$files_prefix."_*"); return true; } if ($format == "MPEG-4") { $mpeg4tracks = $this->exec_program("MP4Box -info ".$file_src); $tracks = preg_split("/\n\n/",$mpeg4tracks); $videotrack = false; foreach($tracks as $track) { if (preg_match("/Track # (\d+)[\s\S]*?Visual Stream/",$track,$m)) { $videotrack = $m[1]; } } $audiotrack = false; foreach($tracks as $track) { if (preg_match("/Track # (\d+)[\s\S]*?Audio (Stream|Track)/",$track,$m)) { $audiotrack = $m[1]; } } if ($videotrack === false) return false; $this->exec_program("MP4Box -raw ".$videotrack." ".$file_src." -out ".$files_prefix."_videostream"); if ($audiotrack !== false) $this->exec_program("MP4Box -raw ".$audiotrack." ".$file_src." -out ".$files_prefix."_audiostream"); $this->exec_program("mencoder ".$files_prefix."_videostream -ovc x264 -x264encopts bitrate=".$vb.":subq=".$X264_SUBQ.":frameref=".$X264_FRAMEREF.":me=".$X264_ME.":bframes=".$X264_BFRAMES.":threads=".$X264_THREADS.":keyint=".$X264_KEYINT." -of rawvideo -vf scale=".$width.":".$height." -ofps ".$fps." -nosound -o ".$files_prefix."_videostream.x264"); if ($audiotrack !== false) $this->exec_program("ffmpeg -i ".$files_prefix."_audiostream -strict experimental -acodec aac -ab ".$ab." -ac 2 ".$files_prefix."_audiostream.aac"); if ($audiotrack !== false) $this->exec_program("MP4Box -new -add ".$files_prefix."_videostream.x264 -fps ".$fps." -add ".$files_prefix."_audiostream.aac ".$file_dst.""); else $this->exec_program("MP4Box -new -add ".$files_prefix."_videostream.x264 -fps ".$fps." ".$file_dst.""); $this->exec_program("rm -f ".$files_prefix."_*"); return true; } if ($format == "AVI")//Format Audio Video Interleave { // dump audio $this->exec_program("mplayer -quiet ".$file_src." -ao pcm:fast:file=".$files_prefix."_audiostream -vc dummy -vo null -channels 2"); // encode video from src $this->exec_program("mencoder ".$file_src." -ovc x264 -x264encopts bitrate=".$vb.":subq=".$X264_SUBQ.":frameref=".$X264_FRAMEREF.":me=".$X264_ME.":bframes=".$X264_BFRAMES.":threads=".$X264_THREADS.":keyint=".$X264_KEYINT." -of rawvideo -vf scale=".$width.":".$height." -ofps ".$fps." -nosound -o ".$files_prefix."_videostream.x264"); // encode audio $this->exec_program("ffmpeg -i ".$files_prefix."_audiostream -strict experimental -acodec aac -ab ".$ab." -ac 2 ".$files_prefix."_audiostream.aac"); $this->exec_program("MP4Box -new -add ".$files_prefix."_videostream.x264 -fps ".$fps." -add ".$files_prefix."_audiostream.aac ".$file_dst.""); $this->exec_program("rm -f ".$files_prefix."_*"); return true; } if ($format == "Windows Media")//WMV { // dump audio $this->exec_program("mplayer -quiet ".$file_src." -ao pcm:fast:file=".$files_prefix."_audiostream -vc dummy -vo null -channels 2"); // encode video from src $this->exec_program("mencoder ".$file_src." -ovc x264 -x264encopts bitrate=".$vb.":subq=".$X264_SUBQ.":frameref=".$X264_FRAMEREF.":me=".$X264_ME.":bframes=".$X264_BFRAMES.":threads=".$X264_THREADS.":keyint=".$X264_KEYINT." -of rawvideo -vf scale=".$width.":".$height." -ofps ".$fps." -nosound -o ".$files_prefix."_videostream.x264"); // encode audio $this->exec_program("ffmpeg -i ".$files_prefix."_audiostream -strict experimental -acodec aac -ab ".$ab." -ac 2 ".$files_prefix."_audiostream.aac"); $this->exec_program("MP4Box -new -add ".$files_prefix."_videostream.x264 -fps ".$fps." -add ".$files_prefix."_audiostream.aac ".$file_dst.""); $this->exec_program("rm -f ".$files_prefix."_*"); return true; } if ($format == "Flash Video")//FLV { // dump audio $this->exec_program("mplayer -quiet ".$file_src." -ao pcm:fast:file=".$files_prefix."_audiostream -vc dummy -vo null -channels 2"); // encode video from src $this->exec_program("mencoder ".$file_src." -ovc x264 -x264encopts bitrate=".$vb.":subq=".$X264_SUBQ.":frameref=".$X264_FRAMEREF.":me=".$X264_ME.":bframes=".$X264_BFRAMES.":threads=".$X264_THREADS.":keyint=".$X264_KEYINT." -of rawvideo -vf scale=".$width.":".$height." -ofps ".$fps." -nosound -o ".$files_prefix."_videostream.x264"); // encode audio $this->exec_program("ffmpeg -i ".$files_prefix."_audiostream -strict experimental -acodec aac -ab ".$ab." -ac 2 ".$files_prefix."_audiostream.aac"); $this->exec_program("MP4Box -new -add ".$files_prefix."_videostream.x264 -fps ".$fps." -add ".$files_prefix."_audiostream.aac ".$file_dst.""); $this->exec_program("rm -f ".$files_prefix."_*"); return true; } return false; }
VP9
- https://trac.ffmpeg.org/wiki/Encode/VP9
- https://www.youtube.com/watch?v=K6JshvblIcM
- https://ru.wikipedia.org/wiki/VP9