منبع حقیقت، محتوا، انتشار و رسانه · فصل ۴ — Media Library، Factory، FFmpeg، Workbench و QA · 167
FFmpeg برای Codec, Filtergraph, Audio و Subtitle
محتوا یا media تولید میکند اما provenance، rights، version، approval و release boundary را یک سیستم واحد نمیبیند. موضوع جاری: «FFmpeg برای Codec, Filtergraph, Audio و Subtitle». میتواند «FFmpeg برای Codec, Filtergraph, Audio و Subtitle» را در یک pipeline محدود با provenance، rights/version و publication gate تعریف کند.
خلاصهٔ درس
محتوا یا media تولید میکند اما provenance، rights، version، approval و release boundary را یک سیستم واحد نمیبیند. موضوع جاری: «FFmpeg برای Codec, Filtergraph, Audio و Subtitle».
میتواند «FFmpeg برای Codec, Filtergraph, Audio و Subtitle» را در یک pipeline محدود با provenance، rights/version و publication gate تعریف کند.
خروجی این درس
میتواند «FFmpeg برای Codec, Filtergraph, Audio و Subtitle» را در یک pipeline محدود با provenance، rights/version و publication gate تعریف کند.
1. فایل پخششونده لزوماً خروجی درست نیست
فرض کنید ورودی یک video stream، دو audio track و یک subtitle دارد. خروجی نهایی بدون خطا ساخته میشود و حتی در player پخش میشود، اما صدای track اول بهجای track دوم انتخاب شده است. این شکست مهم است چون exit code صفر فقط میگوید فرایند FFmpeg تمام شده؛ ثابت نمیکند قرارداد رسانهای موردنظر اجرا شده است. در CON-016، موفقیت یعنی command contract صریح باشد و خروجی با ffprobe دوباره علیه همان contract بررسی شود.
2. مرز مالکیت CON-016
خروجی این درس FFmpeg Execution Contract & Probe Verification Matrix v1 است. این درس reproducibility عمومی recipe را مالک نیست؛ آن مرز متعلق به CON-015 است. Variant branching متعلق به CON-017 و publication/QA متعلق به CON-018 و CON-022 است. اینجا فقط میپرسیم: آیا stream، codec، filter، audio، subtitle و container دقیقاً همان چیزی شدهاند که قبل از اجرا اعلام کرده بودیم؟
3. قبل از command، inventory ورودی را ببند
قبل از نوشتن -map باید stream inventory داشته باشی: index، type، language، codec، sample rate، channel layout، subtitle type و هر metadata لازم. تصمیم روی filename یا «اولین trackی که player نشان میدهد» قابل اتکا نیست. اگر inventory ناقص است، contract باید UNKNOWN بماند؛ حدس زدن index یا language بهمعنی ساختن evidence است.
4. -map انتخاب stream را صریح میکند
FFmpeg وقتی -map وجود نداشته باشد میتواند streamها را خودکار انتخاب کند. این رفتار برای commandهای سریع مفید است، اما برای pipeline قابل ممیزی خطر دارد. وقتی contract میگوید audio دوم یا stream با نقش مشخص لازم است، inclusion باید explicit باشد. -map کنترل میکند کدام stream وارد خروجی شود؛ codec option مرحلهی دیگری است و نباید این دو را یکی فرض کرد.
5. Stream selection با stream handling یکی نیست
پس از selection، encoder/codec برای stream انتخابشده اعمال میشود. اگر codec صریح نباشد، muxer میتواند encoder پیشفرض خودش را انتخاب کند. بنابراین matrix باید دو سؤال جدا داشته باشد: «کدام stream وارد شد؟» و «با چه codec/handlingای نوشته شد؟». خروجیای که stream درست ولی codec اشتباه دارد هنوز contract را پاس نکرده است.
6. Simple و Complex Filtergraph را قاطی نکن
Simple filtergraph به یک output stream متصل است؛ complex filtergraph میتواند چند input/output داشته باشد. contract باید مشخص کند filter کجا اعمال میشود، input آن چیست و output مورد انتظارش کدام است. نوشتن یک رشته filter که syntactically valid است کافی نیست؛ post-run evidence باید نشان دهد نتیجه تکنیکی مورد انتظار—مثلاً resolution یا audio rate—واقعاً در output وجود دارد.
7. Labeled outputهای complex graph باید دقیق map شوند
در complex filtergraph، output pad برچسبدار باید به output موردنظر map شود. stale شدن label در filtergraph یا -map میتواند command را fail کند یا wiring را از intent جدا سازد. در contract، label و map expression با هم version میشوند. هیچ «نزدیکترین label» یا fallback ضمنی در evidence contract مجاز نیست.
8. Audio فقط codec نیست: sample rate و channel layout هم contract هستند
برای audio باید حداقل track identity، codec، sample rate و channel layout مورد انتظار روشن باشد. اگر ورودی از stereo به 5.1 تغییر کرد، pipeline باید تصمیم بگیرد: downmix عمدی انجام میدهد، 5.1 را حفظ میکند، یا fail میشود. تغییر silently از 5.1 به stereo بدون declaration یک AUDIO_MISMATCH است حتی اگر فایل خوشصدا بهنظر برسد.
9. Subtitle رفتار ویژه و compatibility واقعی دارد
Subtitle streamها فقط «وجود دارد/ندارد» نیستند؛ text-based و image-based بودن، encoder و container مقصد اهمیت دارند. FFmpeg در برخی سناریوهای subtitle قواعد انتخاب ویژه دارد و صرف تعیین subtitle encoder تضمین نمیکند conversion یا container compatibility درست است. اگر target text subtitle میخواهد اما source image-based است، contract باید compatibility را ثابت کند یا SUBTITLE_UNSUPPORTED بدهد.
10. Container هم بخشی از contract است
یک set از streamها ممکن است برای یک container مناسب و برای container دیگر نامناسب باشد. پس matrix باید container مقصد، expected output streams و codec/subtitle mode را کنار هم ببیند. تغییر MP4 به MKV یا برعکس صرفاً عوض کردن extension نیست؛ contract باید از نو بررسی شود و unsupported combination به failure تایپشده تبدیل شود.
11. ffprobe شاهد فنی پس از اجراست
ffprobe ابزار رسمی FFmpeg برای استخراج اطلاعات container و stream بهشکل قابلپردازش است. در این درس، probe evidence نقش «واقعیت فنی مشاهدهشده» را دارد: index/type/codec/sample rate/channel layout/resolution/subtitle و format. اما probe معنای محتوا، rights، accessibility، aesthetic quality یا approval را ثابت نمیکند؛ فقط technical output contract را میسنجد.
12. Mismatch را تایپ کن، نه اینکه با PASS مبهم بپوشانی
بهجای یک boolean کلی، failure state باید دقیق باشد: STREAM_MISMATCH، CODEC_MISMATCH، FILTERGRAPH_MISMATCH، AUDIO_MISMATCH، SUBTITLE_UNSUPPORTED، CONTAINER_MISMATCH یا UNKNOWN. این تفکیک repair را هدفمند میکند. اگر دو dimension همزمان fail شدهاند، decision BLOCK است و reason باید dimensionهای شکستخورده را نام ببرد.
13. Matrix: Expected در برابر Observed
هر row از matrix باید input/stream identity، include intent، map expression، codec/filter/audio/subtitle/container expectation و ffprobe observed را کنار هم نگه دارد. Match از مقایسه این دو ساخته میشود، نه از exit code. مهم است که observed data از probe واقعی/fixture ثبتشده بیاید و expectation از contract؛ یکی را از دیگری تولید نکن.
14. Lab: هشت fixture و 64 assertion
Lab شامل baseline سالم و failureهای عمداً طراحیشده است: automatic/wrong audio selection، stale filter label، subtitle ناسازگار، codec پیشفرض نامنتظر، audio layout mismatch، container mismatch و transfer با دو subtitle و 5.1. Oracle مخفی برای هر fixture هشت field را بررسی میکند؛ در مجموع 64 assertion. learner فقط fixture و starter را میبیند، نه expected labels.
15. Transfer: subtitle دوم، 5.1 و container جدید
در transfer، input یک subtitle دوم میگیرد، audio به 5.1 تغییر میکند و target container عوض میشود. تصمیم قبلی قابل کپی نیست. inventory، map، codec، filter، downmix/preserve policy و subtitle mode دوباره ساخته میشوند و probe evidence جدید با contract تازه مقایسه میشود. نتیجه فقط وقتی EXECUTION_VERIFIED است که همه dimensionهای فنی بسته باشند؛ این نتیجه مجوز انتشار نیست.
ارزیابی
پاسخنامهی این درس در بستهی آموزش وجود ندارد؛ خودت جواب بده و صادقانه علامت بزن. «نیاز به مرور» درس را به صف تکرار میفرستد.
Q1 application
An input has two audio streams and the intended language is the second stream. Which contract fields make selection auditable?
Q2 diagnosis
FFmpeg exits zero but ffprobe shows the wrong audio track. What failure state applies?
Q3 decision
A complex-filter output label changed but the map expression did not. Can the derivative leave the execution stage?
Q4 transfer
Add a second subtitle stream, change stereo to 5.1, and switch MP4 to MKV. Which expectations must be rebuilt?
Q5 reflection
State one technical claim ffprobe evidence can support and one publication claim it cannot support.
ملاکهای ارزیابی (rubric)
Critical dimensions: exact input/stream identity, explicit mapping, codec/filter/audio/subtitle/container expectation, observed probe evidence, typed mismatch preservation, and changed-context transfer.
A sufficient submission never treats exit code zero, playability, automatic selection, or a default codec as proof of the declared output contract, and never turns EXECUTION_VERIFIED into publication approval.
منابع و تازگی
مطالعهٔ موارد (case studies)
فایلهای آزمایشگاه
Evaluate the supplied synthetic fixtures against explicit stream mapping, codec, filtergraph, audio, subtitle, and container expectations.
A playable file or zero process exit code is not an oracle. Use exact fixture fields and preserve typed mismatches. Run python run_checks.py to validate the fixture shape before implementing starter.py.