با سلام و احترام خدمت بازدیدکنندگان عزیز
آموزش و آشنایی با نرم افزار FFmpeg – قسمت هشتم – فیلترها یا Filtergraph (سه)
برای مشاهده قسمت اول به این پست مراجعه نمایید.
برای مشاهده قسمت دوم به این پست مراجعه نمایید.
برای مشاهده قسمت سوم به این پست مراجعه نمایید.
برای مشاهده قسمت چهارم به این پست مراجعه نمایید.
برای مشاهده قسمت پنجم به این پست مراجعه نمایید.
برای مشاهده قسمت ششم به این پست مراجعه نمایید.
برای مشاهده قسمت هفتم به این پست مراجعه نمایید.


فیلتر گذاری از نوع پیچیده:
Complex Filtergraph:
فیلترگراف پیچیده چیزی مانند فیلترچِین که در دو پست گذشته مشاهده کردیم می باشد. با این تفاوت که برخلاف سوئیچ -filter، برای یک نوع استریم خاص و یک استریم با یک اندیس خاص تعریف نمی شود. بلکه یک سوئیچ کلی هست (-filter_complex یا مشابه اون که -lavfi هست) و تفاوتش این است که برای چند استریم بصورت همزمان استفاده می شود. یک سوئیچ برای همه. یعنی 1 یا بیش از 1 استریم می تواند ورودی بگیرد و 1 یا بیش از 1 استریم خروجی بدهد. صرف نظر از نوع استریم. مثلا یک استریم صدا به عنوان ورودی بگیرد و سه کپی از آن تولید کند و به هر یک از آنها فیلترهای جداگانه ای اعمال کند و در نهایت، سه استریم صدا خروجی بدهد یا دوتایشان را باهم میکس کند و دو استریم خروجی بدهد و در همین زمان یک استریم ویدئویی بگیرد و فیلتر گذاری کند و خروجی بدهد.
مدیریت استریم ها در داخل آن بوسیله لیبل گذاری (تقریباً مانند همان مَپ کردن که در پست های ابتدایی مبحث آموختیم) انجام می گیرد. برخی از فیلتر های FFmpeg حتما به دو ورودی نیاز دارند. مثلا فیلتر overlay یا فیلتر sidechaincompress هردو به دو استریم ورودی نیاز داشته و در فیلتر گذاری ساده (مانند قسمت های ششم و هفتم مبحث) اصلا نمی توانند استفاده بشوند. در فیلترگراف پیچیده هر Filterchain یک ورودی دارد و یک خروجی که به ترتیب input pad و output pad آن فیلترچِین نامیده میشود. هر لیبل نیز باید به یک pad ورودی و یک pad خروجی متصل بشود.
در زیر مثالی بسیار ساده از نحوه لیبل گذاری اجرا می کنیم که در اون، یک فایل صوتی ac3 باز می کنیم و دو خروجی جداگانه یکی با فرمت ac3 و یکی با فرمت opus ازش می گیریم بصورت همزمان:
"%FFmpeg%" -i ".\samples\audio 2ch 256k.ac3" -filter_complex [0:a:0]asplit[seda_out1][seda_out2] -map [seda_out1] -b:a 448K ".\sample1.ac3" -map [seda_out2] -b:a 160K ".\sample2.opus"
نکته: در نام لیبل، فقط از کارکترهای a تا z (هم بزرگ و هم کوچک) و 0 تا 9 و خط ربط یا همان "_" استفاده می کنیم و باید بین دوتا "]" و "[" قرار داده بشود.
نکته 2: فیلتر asplit برای گرفتن کپی از استریم های صوتی استفاده میشه و مشابه اون فیلتر split هست که برای کپی استریم های ویدئویی استفاده میشه. در مثال بعدی متوجه خواهید شد که چرا با این دو شروع کردیم.
نکته 3: در مثال بالا ما بجای نوشتن -map همیشگی خودمون بعد از فایل ورودی، مقداری که جلوی اون مینوشتیم را (یعنی همان 0:a:0 را) بجای لیبل ورودی فیلتر asplit نوشتیم که شد input pad اون فیلترچِین.
نکته 4: با تعیین دو لیبل بعد از asplit، بهش فهموندیم که ازش می خواهیم از چیزی که بهش ورودی دادیم دو کپی بدهد. و در ادامه دیدید که لیبل های خروجی را در مکان های دلخواه با سوئیچ -map فراخوانی کردیم و در اصل output pad فیلترچِین را تعیین تکلیف کردیم. گاهی که تعداد لیبل ها و فیلترهای شما زیاد می شود و فیلترگرافتون واقعا پیچیده می شود اگر فراموش کنید برای input pad و output pad حتی یکی از فیلترچِین ها تعیین تکلیف کنید با خطا مواجه خواهید شد.
مثال بعدی همان مثال بالایی هست منتهی این سری به هر کدام از خروجی های asplit باز فیلترهای جداگانه ای اعمال می کنیم:
"%FFmpeg%" -i ".\samples\audio 2ch 256k.ac3" -filter_complex [0:a:0]asplit[s1][s2];[s1]earwax[out1];[s2]vibrato=6.0,volume=-6dB[out2] -map [out1] -b:a 448K ".\sample1.ac3" -map [out2] -b:a 160K ".\sample2.opus"
نکته: اول یک مقداری فکر کنید ببینید دلیل وجود فیلترهای asplit و split چیست... چرا از همون 0:a:0 در چند جا استفاده نشد...
دلیل این هست که در فیلترگراف پیچیده از هر لیبل فقط یکبار می شود استفاده کرد. توانایی تعریف یک لیبل با نام یکسان در دوجای متفاوت وجود ندارد. یک لیبل باید یکبار بوجود بیاید و یکبار استفاده بشود. مثلا در مثال بالا [s1] بوجود آمد و استفاده شد. حالا اگر در انتهای کل فیلترگراف باز بخواهید از [s1] استفاده کنید و مثلا [out3] بگیرید با خطای matches no stream مواجه خواهید شد زیرا دیگر وجود ندارد. همچنین در نکته های مثال قبلی از تعیین و تکلیف کردن pad ها گفته شد. برای امتحان می توانید در دستور بالا یک =3[s0] خالی بین asplit و [s1] که بهش چسبیده اضافه کنید و اجرا کنید تا خطای Filter asplit:output0 has a unconnected output... را مشاهده کنید.
نکته 2: با تعریف Filterchain در قسمت ششم مبحث آشنا شدیم. در مثال بالا نیز با تعریف filtergraph آشنا شدیم که مجموعه ای از Filterchain هاست که با سِمی کولُن یا همان ";" از هم جدا شدند.

--پایان قسمت هشتم