はじめに
こんにちは streampack チームのメディです。
https://cloudpack.jp/service/option/streampack.html
Copyrights
Sintel
© copyright Blender Foundation | www.sintel.org
What is CMAF ・ CMAFとは
CMAF means Common media application format
In order to simplify let’s say that CMAF has support for both MPEG-DASH and HLS. You just need to create your video segments once. Both of the manifests (MPD & m3u8) will use the same video segments.
CMAFは「Common media application format」を意味します。
単純化するため、CMAFがMPEG-DASHとHLSの両方をサポートしているとしましょう。 あなたは一度あなたのビデオセグメントを作成する必要があります。 両方のマニフェスト(MPD & m3u8)は同じビデオセグメントを使用します。
Objective・目的
Learning how to create a CMAF compliant on demand video stream.
オンデマンドのCMAFのビデオストリームの簡単な例を学ぶこと。
Tools ・ツール
FFMPEG
FFMPEG will encode the video file.
FFMPEGはビデオファイルをエンコードします。
I am using a static build of FFMPEG v4.1.
FFMPEG「v4.1」の静的ビルドを使用しています。
FFMPEG static builds ・ FFMPEG静的ビルド
Bento4
Bento will create CMAF fragmented MP4 files with the associated manifests for HLS and MPEG-Dash.
Bentoは、HLSおよびMPEG-Dashの関連するマニフェストを含むCMAF断片化された MP4 ファイルを作成します。
https://github.com/axiomatic-systems/Bento4
CMAF creation on OSX ・ OSXでのCMAFの作成方法
brew install p7zip wget https://evermeet.cx/ffmpeg/ffmpeg-4.1.7z 7za x ffmpeg-4.1.7z
rm ffmpeg-4.1.7z
I was not able to use the Bento4 builds for my system, so I had to compile it.
Bento4ビルドを私のシステムに使用することができなかったため、コンパイルする必要がありました。
If you want to try the Bento4 builds for your system, please check this page.
あなたのシステム用のBento4ビルドを試したい場合は、このページをチェックしてください。
cd mkdir cmaf cd cmaf git init git clone https://github.com/axiomatic-systems/Bento4.git
In the Bento4 folder please open the following file with Xcode :
Bento4フォルダにXcodeで次のファイルを開きます:Build/Targets/universal-apple-macosx/Bento4.xcodeproj
Then click: Product > Build
次に、Product> Buildをクリックします。
In this example, we use Xcode on OSX, for other systems & IDE, please refer to this page
この例では、OSX上でXcodeを使用しています。他のシステムとIDEについては、このページを参照してください。
By default, on OSX, your builds will be located in:
デフォルトでは、OSXではビルドは次の場所にあります。~/Library/Developer/Xcode/DerivedData/
For example in my case, the full path of the build directory is:
たとえば私の場合、ビルドディレクトリのフルパスは次のようになります。
/Users/mehdi/Library/Developer/Xcode/DerivedData/Bento4-csvbfwwtinqvwpdlscgeezmabnlx/Build/Products/Debug
Shell script ・ シェルスクリプト
This shell script will use FFMPEG & Bento4 to generate a CMAF stream from a mp4 video.
このシェルスクリプトは、FFMPEGとBento4を使用して mp4 ビデオからCMAFストリームを生成します。
#! /bin/sh # Current working directory cwd="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" file="${cwd}/sintel-1024-surround.mp4" timestamp=`date +%s` ffmpeg="${cwd}/ffmpeg" #v 4.1. vb_array=(500 1000 2000) # video bitrates in kbps x264encoder="libx264" # software encoder : libx264 , OSX hardware acceleration : h264_videotoolbox #You REALLY should use hardware acceleration :-) https://trac.ffmpeg.org/wiki/HWAccelIntro #TODO CHANGE FILE PATH mp4dash="/Users/mehdi/cmaf/Bento4/Source/Python/utils/mp4-dash.py" # v1.5.1-627 #TODO CHANGE FILE PATH bento4Builds="/Users/mehdi/Library/Developer/Xcode/DerivedData/Bento4-csvbfwwtinqvwpdlscgeezmabnlx/Build/Products/Debug" # Compiled with Xcode echo "Creating a working directory : $timestamp" mkdir -p "${timestamp}" echo "Creating an output directory : output/${timestamp}" mkdir -p "output/${timestamp}" echo "Audio extraction & encoding" ffmpeg -i "${file}" \ -f mp4 -map 0:1 -movflags frag_keyframe+empty_moov+default_base_moof+faststart -vn -strict experimental -c:a aac -b:a 128k -f mp4 -frag_duration 4000000 "${timestamp}"/audio_only.fmp4 echo "Video extraction & encoding" for bitrate in "${vb_array[@]}"; do ffmpeg -i "${file}" \ -f mp4 -map 0:0 -movflags frag_keyframe+empty_moov+default_base_moof+faststart -bf 2 -g 90 -sc_threshold 0 -an -strict experimental -profile:v baseline -frag_duration 4000000 -c:v "${x264encoder}" -b:v "${bitrate}k" "${timestamp}"/video_only_"${bitrate}"k.fmp4 done echo "Creating CMAF VOD streams" ${mp4dash} -f -o ${cwd}/output/${timestamp} -v --hls --profiles=onDemand --use-segment-timeline ${cwd}/${timestamp}/*.fmp4 --exec-dir=${bento4Builds} echo "Your files have been saved in ${cwd}/output/${timestamp}"
Created files ・ 作成されたファイル
In video/avc1 we have 3 folders, because we chose 3 different video bitrates (500, 1000 & 2000 kbps).
video/avc1 では、3つの異なるビデオビットレート(500,1000,2000 kbps)を選択しているので、3つのフォルダがあります。
Javascript player : Plyr
Plyr is an open sources javascript media player.
Plyr はオープンソースのjavascriptメディアプレーヤーです。
If you are interested in Plyr, I wrote a more detailed article.
Plyr に興味がある場合は、より詳細な記事にあります。
Note about old web browsers ・ 古いウェブブラウザについて
To support old browsers, I use the polyfill version of plyr.
古いブラウザをサポートするために、plyr の polyfill 版を使用します。
<!-- Plyr --> <script src="//cdn.plyr.io/3.4.7/plyr.polyfilled.js"></script>
I also hide the big central button onPlay to avoid issues on some browsers.
いくつかのWebブラウザでの不具合を避けるために、onPlay イベントが発生したときに大きな再生ボタンを非表示にします。
// To support old browsers, you may want to hide the big central play button. document.getElementsByClassName('plyr__control--overlaid')[0].style.visibility = 'hidden';
Implementation ・ 実装
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Plyr CMAF</title> <!-- Plyr style sheet --> <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/plyr/3.4.7/plyr.css" /> </head> <body> <!-- HLS support --> <script src="//cdn.jsdelivr.net/hls.js/latest/hls.js"></script> <!-- MPEG Dash support --> <script src="//cdnjs.cloudflare.com/ajax/libs/dashjs/2.9.2/dash.all.debug.js"></script> <!-- Plyr --> <script src="//cdn.plyr.io/3.4.7/plyr.polyfilled.js"></script> <video preload="none" id="player" controls crossorigin> <!-- **** Don't forget to change the source paths ! **** --> <source src="output/1545184765/master.m3u8" type="application/x-mpegURL"> <source src="output/1545184765/stream.mpd" type="application/dash+xml"> </video> </body> <script type="text/javascript"> var isDebug = true; var video = document.querySelector('#player'); var sources = video.getElementsByTagName('source'); // Detecting browser capabilities var canUseDash = false; var obj = document.createElement('video'); if (obj.canPlayType('application/dash+xml')) { canUseDash = true; } if (canUseDash) { // MPEG-DASH var mpd = sources[1].src var dash = dashjs.MediaPlayer().create(); dash.initialize(video, mpd, false); } else { // HLS var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); // Safari supports HLS natively, we don't want to use HLS.js if (!isSafari && Hls.isSupported()) { var hlsSrc = sources[0].src; var hls = new Hls(); hls.loadSource(hlsSrc); hls.attachMedia(video); } } var player = new Plyr(video, { resetOnEnd: true, debug: isDebug }); // To avoid problems on old browsers, you may want to hide the big central play button when onPlay if fired player.on('play', function(e) { document.getElementsByClassName('plyr__control--overlaid')[0].style.visibility = 'hidden'; }); player.on('pause', function(e) { document.getElementsByClassName('plyr__control--overlaid')[0].style.visibility = ''; }); </script> </html>
Compatibility ・ウェブブラウザの互換性
Windows specific browsers
Windows Version | Browser | Compatibility |
---|---|---|
Windows 10 | EDGE (15,16,17,18) | YES |
Windows 10 | Internet Explorer 11 | YES |
Windows 8.1 | Internet Explorer 11 | YES |
Windows 7 | Internet Explorer 11 | NO 🙁 |
Mac OS specific browsers
OSX Version | Browser | Compatibility |
---|---|---|
Mojave | Safari 12 | YES |
High Sierra | Safari 11.1 | YES |
Sierra | Safari 10.1 | YES |
ElCapitan | Safari 9.1 | YES |
Multi platform desktop browsers
Browser | Compatibility |
---|---|
Firefox 45 | YES |
Firefox 64 | YES |
Chrome 40 | YES |
Chrome 71 | YES |
Android
OS Version | Browser | Compatibility |
---|---|---|
Android 4.4 | Chrome: | YES |
Android 4.4 | Firefox: | YES |
Android 8 | Chrome: | YES |
Android 8 | Firefox: | YES |
iOS
OS Version | Browser | Compatibility |
---|---|---|
iOS 12 | Safari 12 | YES |
iOS 12 | Chrome: | YES |
iOS11 | Safari 12 | YES |
iOS 11 | Chrome | YES |
iOS 10 | Safari 10 | YES |
iOS 10 | Chrome | YES |
iOS 9 | Safari 9 | NO 🙁 |
iOS 9 | Chrome | NO 🙁 |
Sources
Tools
http://bento4.com/documentation
https://www.ffmpeg.org/ffmpeg-all.html
A more complete CMAF creation script
https://gist.github.com/GnaphronG/ad239570c47141d89a9282913607d83f
Player capabilities detection
https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/canPlayType
Plyr javascript media player
https://github.com/sampotts/plyr
CMAF with AWS MediaConvert
https://qiita.com/tomopyonsama/items/e4d58af20928cab41cb5
About CMAF
https://blogs.akamai.com/2016/06/cmaf-what-it-is-and-why-it-may-change-your-ott-future.html
https://blogs.akamai.com/jp/2018/04/cmaf-cmaf-low-lalatency-live.html
https://developer.apple.com/documentation/http_live_streaming/about_the_common_media_application_format_with_http_live_streaming
https://bitmovin.com/what-is-cmaf-threat-opportunity/