FFmpeg का इस्तेमाल करके VP9 फ़ॉर्मैट में लाइव एन्कोडिंग करना

पैरामीटर को कोड में बदलने के तरीके

VP9, लाइव एन्कोडिंग को ऑप्टिमाइज़ करने के लिए कई पैरामीटर उपलब्ध कराता है. इनके कुछ सामान्य सिद्धांतों के बारे में बिटरेट मोड में बताया गया है.

FFmpeg VP9 एन्कोडिंग का उदाहरण

नीचे दी गई टेबल में, VP9 एन्कोडिंग के लिए ffmpeg कॉल के उदाहरण के पैरामीटर के बारे में बताया गया है.

पैरामीटर ब्यौरा
-quality realtime realtime, लाइव स्ट्रीमिंग और 5 से ज़्यादा स्पीड के लिए ज़रूरी है.
-speed 6 लाइव / रीयल-टाइम एन्कोडिंग के लिए, स्पीड 5 से 8 तक का इस्तेमाल किया जाना चाहिए. कम नंबर (5 या 6) वाली सेटिंग से बेहतर क्वालिटी मिलती है, लेकिन इसके लिए ज़्यादा सीपीयू पावर की ज़रूरत होती है. ज़्यादा संख्या (7 या 8) का मतलब है कि क्वालिटी कम होगी. हालांकि, इससे कम समय में डेटा ट्रांसफ़र करने में मदद मिलेगी. साथ ही, यह कम सीपीयू पावर वाले डिवाइसों, जैसे कि मोबाइल के लिए भी बेहतर है.
-tile-columns 4 टाइलिंग की मदद से, वीडियो को आयताकार हिस्सों में बांटा जाता है. इससे एन्कोडिंग और डिकोडिंग के लिए मल्टी-थ्रेडिंग की सुविधा मिलती है. टाइलों की संख्या हमेशा दो की घात होती है. 0 = 1 टाइल, 1 = 2, 2 = 4, 3 = 8, 4 = 16, 5 = 32.
-frame-parallel 1 पैरलल डीकोड करने की सुविधाएं चालू करें.
-threads 8 इस्तेमाल की जाने वाली थ्रेड की ज़्यादा से ज़्यादा संख्या.
-static-thresh 0 हलचल का पता लगाने के लिए थ्रेशोल्ड.
-max-intra-rate 300 ज़्यादा से ज़्यादा आई-फ़्रेम बिटरेट (प्रतिशत)
-deadline realtime -quality realtime का वैकल्पिक (लेगसी) वर्शन
-lag-in-frames 0 लैग करने के लिए फ़्रेम की ज़्यादा से ज़्यादा संख्या
-qmin 4 -qmax 48 क्वांटाइज़र के लिए कम से कम और ज़्यादा से ज़्यादा वैल्यू. यहां दी गई वैल्यू सिर्फ़ एक सुझाव है. इसे अडजस्ट करने से, वीडियो की क्वालिटी को कम या ज़्यादा किया जा सकता है. हालांकि, इससे वीडियो का साइज़ कम करने की क्षमता पर असर पड़ेगा.
-row-mt 1 लाइन-मल्टीथ्रेडिंग चालू करें. इससे टाइल कॉलम के तौर पर, ज़्यादा से ज़्यादा दो थ्रेड का इस्तेमाल किया जा सकता है. 0 = बंद है, 1 = चालू है.
-error-resilient 1 गड़बड़ी ठीक करने की सुविधाएं चालू करें.

एन्कोडिंग पैरामीटर चुनना

यहां दी गई जानकारी में, अडैप्टिव बिटरेट स्ट्रीमिंग (एबीआर) के लिए कॉन्स्टेंट बिटरेट (सीबीआर) एन्कोडिंग का इस्तेमाल किया गया है. इसमें हर टारगेट रेट को पैक करने वाले सॉफ़्टवेयर के मेनिफ़ेस्ट में साफ़ तौर पर सेट किया जाता है. इससे क्लाइंट के लिए, किराये के बीच "स्विच" करना आसान हो जाएगा. अगर बिटरेट को ज़्यादा फ़्लेक्सिबल बनाया जा सकता है या एन्कोडिंग को छोटे-छोटे हिस्सों में बांटा जा रहा है, तो वैरिएबल बिटरेट (वीबीआर) एन्कोडिंग और सीक्यू मोड का भी इस्तेमाल किया जा सकता है. Q मोड में, लाइव वीडियो के लिए ज़रूरी रीयलटाइम एन्कोडिंग में समस्या आएगी. ज़्यादा जानकारी के लिए, बिटरेट मोड देखें.

VP9 में बदलाव करने के तरीके के बारे में ज़्यादा जानकारी के लिए, वीओडी सेटिंग के बारे में बताने वाला लेख पढ़ें. हालांकि, इसमें CBR पर फ़ोकस किया गया है.

सुझाव और तरकीबें

ध्यान रखें कि लाइव स्ट्रीमिंग के दौरान, हर चीज़ को कम से कम 1x की रीयलटाइम एन्कोडिंग स्पीड तक सीमित किया जाता है. FFmpeg, एन्कोडिंग की प्रोसेस के दौरान एन्कोडिंग की स्पीड की जानकारी देता है. अगर एन्कोडिंग की स्पीड 1x से कम हो जाती है, तो लाइव वीडियो के इनपुट के साथ एन्कोडिंग प्रोसेस जारी नहीं रहेगी. साथ ही, उपयोगकर्ताओं को बफ़रिंग की समस्या आएगी और ट्रांसमिशन में रुकावटें आएंगी. इससे लाइव ब्रॉडकास्ट के दौरान स्ट्रीम का इस्तेमाल नहीं किया जा सकेगा. हालांकि, आम तौर पर स्ट्रीम को संग्रह में इस्तेमाल किया जा सकेगा.

पैरामीटर को कोड में बदलने के उदाहरण

यहां Linux पर चलने वाले क्वाड-कोर i5 3.6Ghz डेस्कटॉप पर, अलग-अलग फ़्रेम साइज़ के लिए 25 फ़्रेम प्रति सेकंड (एफ़पीएस) पर सीपीयू के इस्तेमाल की जानकारी दी गई है:

समस्या हल करने का टारगेट FFmpeg VP9 पैरामीटर सीपीयू / स्पीड (उदाहरण)
3840x2160 (2160 पिक्सल) -r 30 -g 90 -s 3840x2160 -quality realtime -speed 5 -threads 16 -row-mt 1 -tile-columns 3 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 7800k ~88% 0.39x
2560x1440 (1440 पिक्सल) -r 30 -g 90 -s 2560x1440 -quality realtime -speed 5 -threads 16 -row-mt 1 -tile-columns 3 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 6000k ~86% 0.68x
1920x1080 (1080 पिक्सल) -r 30 -g 90 -s 1920x1080 -quality realtime -speed 5 -threads 8 -row-mt 1 -tile-columns 2 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 4500k ~82% 1.04x
1280x720 (720 पिक्सल) -r 30 -g 90 -s 1280x720 -quality realtime -speed 5 -threads 8 -row-mt 1 -tile-columns 2 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 3000k ~78% 1.77x
854x480 (480 पिक्सल) -r 30 -g 90 -s 854x480 -quality realtime -speed 6 -threads 4 -row-mt 1 -tile-columns 1 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 1800k ~64% 3.51x
640x360 (360 पिक्सल) -r 30 -g 90 -s 640x360 -quality realtime -speed 7 -threads 4 -row-mt 1 -tile-columns 1 -frame-parallel 0 -qmin 4 -qmax 48 -b:v 730k ~62% 5.27x
426x240 (240 पिक्सल) -r 30 -g 90 -s 426x240 -quality realtime -speed 8 -threads 2 -row-mt 1 -tile-columns 0 -frame-parallel 0 -qmin 4 -qmax 48 -b:v 365k ~66% 8.27x

FFmpeg का उदाहरण कुछ ऐसा दिख सकता है:

ffmpeg -stream_loop 100 -i /home/id3as/Videos/120s_tears_of_steel_1080p.webm \
  -r 30 -g 90 -s 3840x2160 -quality realtime -speed 5 -threads 16 -row-mt 1 \
  -tile-columns 3 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 7800k -c:v libvpx-vp9 \
  -b:a 128k -c:a libopus -f webm pipe1

सुझाव और तरकीबें

  • ध्यान दें कि यहां हम आउटपुट को FIFO पाइप ("pipe1") में भेज रहे हैं. इसे FFmpeg कमांड चलाने से पहले, एक्ज़ीक्यूशन से पहले बनाया जाना चाहिए. इसके लिए, अपनी वर्किंग डायरेक्ट्री में mkfifo pipe1 कमांड दें. Shaka Packager का इस्तेमाल करते समय, यह उस पाइप को दी गई स्ट्रीम के लिए इनपुट सोर्स के तौर पर सुनेगा. पैकेजिंग के अन्य मॉडल के लिए, अलग तरीके की ज़रूरत पड़ सकती है.

  • यह पक्का करने के लिए कि -row-mt कमांड को पहचाना जा रहा है, https://www.ffmpeg.org/download.html से FFmpeg का सबसे नया स्टेबल वर्शन (फ़िलहाल, 3.3.3) इस्तेमाल करें

अडैप्टिव बिटरेट सेट का उदाहरण

FFmpeg को चलाने वाली मशीन की क्षमता के आधार पर, हो सकता है कि एक साथ इन सभी एन्कोडिंग को डिलीवर न किया जा सके. इसलिए, सूची में से अपने उपलब्ध संसाधनों और टारगेट ऑडियंस के हिसाब से सबसे सही सबसेट चुनें.

FFmpeg का पूरा ABR सेट

सबसे सही तरीके से काम करने के लिए, हम एन्कोडिंग के उन उदाहरणों को एक साथ जोड़ते हैं जिनके बारे में पिछले सेक्शन में बताया गया है. इससे एक ही कमांड से सभी उदाहरण एक साथ जनरेट हो जाते हैं:

ffmpeg -stream_loop 100 -i lakes1080p.mp4 \
  -y -r 25 -g 75 -s 3840x2160 -quality realtime -speed 5 -threads 8 \
  -tile-columns 2 -frame-parallel 1 \
  -b:v 7800k -c:v libvpx-vp9 -b:a 196k -c:a libopus -f webm pipe1 \
  -y -r 25 -g 75 -s 2560x1440 -quality realtime -speed 5 -threads 8 \
  -tile-columns 2 -frame-parallel 1 \
  -b:v 6000k -c:v libvpx-vp9 -b:a 196k -c:a libopus -f webm pipe2 \
  -y -r 25 -g 75 -s 1920x1080 -quality realtime -speed 5 -threads 4 \
  -tile-columns 2 -frame-parallel 1 \
  -b:v 4500k -c:v libvpx-vp9 -b:a 196k -c:a libopus -f webm pipe3 \
  -y -r 25 -g 75 -s 1280x720 -quality realtime -speed 5 -threads 4 \
  -tile-columns 2 -frame-parallel 1 \
  -b:v 3000k -c:v libvpx-vp9 -b:a 196k -c:a libopus -f webm pipe4 \
  -y -r 25 -g 75 -s 854x480 -quality realtime -speed 6 -threads 4 \
  -tile-columns 2 -frame-parallel 1 \
  -b:v 2000k -c:v libvpx-vp9 -b:a 196k -c:a libopus -f webm pipe5 \
  -y -r 25 -g 75 -s 640x360 -quality realtime -speed 7 -threads 2 \
  -tile-columns 1 -frame-parallel 0 \
  -b:v 730k -c:v libvpx-vp9 -b:a 128k -c:a libopus -f webm pipe6 \
  -y -r 25 -g 75 -s 426x240 -quality realtime -speed 8 -threads 2 \
  -tile-columns 1 -frame-parallel 0 \
  -b:v 365k -c:v libvpx-vp9 -b:a 64k -c:a libopus -f webm pipe7

हालांकि, ऊपर दिए गए पूरे सेट के लिए बहुत दमदार सीपीयू की ज़रूरत होगी. इसके अलावा, हार्डवेयर जीपीयू ऑफलोड की सुविधा भी ज़रूरी हो सकती है. जैसे, कुछ चिपसेट में यह सुविधा पहले से मौजूद होती है. Intel Kabylake (और इसके बाद के वर्शन) में, हार्डवेयर एन्कोडिंग की पूरी पाइपलाइन होती है. (ध्यान दें कि Kabylake GPU, 8-बिट VP9 कोडिंग कर सकता है, लेकिन 10-बिट कोडिंग नहीं).

Shaka Packager का इस्तेमाल करके, डेस्कटॉप पर काम करने वाला उदाहरण

सामान्य डेस्कटॉप मशीनों के लिए, ज़्यादा व्यावहारिक उदाहरण में Shaka Packager का इस्तेमाल किया जा सकता है. Shaka को सेट अप करने का आसान तरीका यह है कि इसे Docker कंटेनर में इंस्टॉल किया जाए. इसके लिए, Google की DockerHub इमेज का इस्तेमाल करें. इससे जुड़े निर्देश यहां दिए गए हैं:

https://github.com/google/shaka-packager#using-docker-for-testing--development

इस उदाहरण के लिए, हमने इस कॉन्फ़िगरेशन वाले मशीन का इस्तेमाल किया है:

सिस्टम होस्ट: obs कर्नेल: 4.4.0-91-lowlatency x86_64 (64 बिट)
डेस्कटॉप Xfce 4.12.3 Distro: OS: https://ubuntustudio.org/2016/10/ubuntu-studio-16-10-released/
सीपीयू क्वाड कोर Intel Core i5-6500 (-MCP-)
कैश: 6144 केबी
क्लॉक स्पीड: ज़्यादा से ज़्यादा: 3600 मेगाहर्ट्ज़ 1: 800 मेगाहर्ट्ज़ 2: 800 मेगाहर्ट्ज़ 3: 800 मेगाहर्ट्ज़ 4: 800 मेगाहर्ट्ज़
ग्राफ़िक्स कार्ड Intel Skylake इंटिग्रेटेड ग्राफ़िक्स
मेमोरी 8 जीबी रैम

असल में, यह मशीन एबीआर एन्कोड की इस रेंज को सबसे सही तरीके से जनरेट कर सकती है. साथ ही, FFmpeg लगातार 1x एन्कोड स्पीड की रिपोर्ट देता है:

ffmpeg -stream_loop 100 -i 120s_tears_of_steel_1080p.webm \
  -y -r 30 -g 90 -s 1920x1080 -quality realtime -speed 7 -threads 8 \
  -row-mt 1 -tile-columns 2 -frame-parallel 1 -qmin 4 -qmax 48 \
  -b:v 4500k -c:v libvpx-vp9 -b:a 128k -c:a libopus -f webm pipe1 \
  -y -r 30 -g 90 -s 1280x720 -quality realtime -speed 8 -threads 6 \
  -row-mt 1 -tile-columns 2 -frame-parallel 1 -qmin 4 -qmax 48 \
  -b:v 3000k -c:v libvpx-vp9 -b:a 128k -c:a libopus -f webm pipe2 \
  -y -r 30 -g 90 -s 640x360 -quality realtime -speed 8 -threads 2 \
  -row-mt 1 -tile-columns 1 -frame-parallel 1 -qmin 4 -qmax 48 \
  -b:v 730k -c:v libvpx-vp9 -b:a 128k -c:a libopus -f webm pipe3

ध्यान दें कि -speed की सेटिंग काफ़ी ज़्यादा हैं. इन सेटिंग को एक्सपेरिमेंट के तौर पर सेट किया गया था. साथ ही, ये मशीन के हिसाब से अलग-अलग होंगी.

Shaka Packager का ओवरहेड

पैकेजिंग में सीपीयू का इस्तेमाल ज़्यादा नहीं होता. Shaka Packager को सभी आउटपुट के लिए सेट किया जा सकता है. भले ही, FFmpeg सिर्फ़ कुछ आउटपुट डिलीवर कर रहा हो. ये पैक करने वाले की सेटिंग हैं, जिनकी जांच ऊपर बताई गई मशीन पर की गई है:

packager \
  in=pipe1,stream=audio,init_segment=livehd-audio-1080.webm,segment_template=livehd-audio-1080-\$Number\$.webm \
  in=pipe1,stream=video,init_segment=livehd-video-1080.webm,template=livehd-video-1080-\$Number\$.webm \
  in=pipe2,stream=audio,init_segment=livehd-audio-720.webm,segment_template=livehd-audio-720-\$Number\$.webm \
  in=pipe2,stream=video,init_segment=livehd-video-720.webm,template=livehd-video-720-\$Number\$.webm \
  in=pipe3,stream=audio,init_segment=livehd-audio-360.webm,segment_template=livehd-audio-360-\$Number\$.webm \
  in=pipe3,stream=video,init_segment=livehd-video-360.webm,template=livehd-video-360-\$Number\$.webm \
  --mpd_output livehd.mpd --dump_stream_info --min_buffer_time=10 --time_shift_buffer_depth=300 \
  --segment_duration=3 --io_block_size 65536