ترمیم زیرنویس‌های نامفهوم با سی‌شارپ

subfixerمن دوست دارم فایلای ویدیویی رو روی سیستم اصلی بریزم و اکثرا با تلویزیون یا لپتاپ تماشا کنم. مشکل اینه که هر برنامه ای یک تعبیر پیشفرض از زیرنویس داره مثلا VLC که روی لپتاپ استفاده می‌کنم تنظیم شده روی UTF-8 یا اکثر تلویزیون‌ها همیشه windows-1256 و UTF-8 رو قبول دارن. اما برنامه (هایی) که عزیزان مترجم ازش استفاده می‌کنن همیشه یا خروجیش UTF-16 هست و یا WINDOWS-1256 که این تداخل باعث می‌شه گاهی وقتا زیرنویس خرچنگ قورباقه نمایش داده بشه.

برای همین می‌خوام سناریوی یک برنامه ساده با سی شارپ رو توضیح بدم که کارش ترمیم زیرنویس‌های نامفهوم و هماهنگ کردن اسم فایلها با اسم ویدیوهاست (توی تصویر مشخصه) – فرض کنید یک سریال ۲۲ قسمتی رو توی چند ثانیه میشه ترمیم کرد درصورتی که حالت عادی آدم خسته میشه از بس اسم‌ها رو تغییر میده بعد سایت به سایت دنبال ترمیم کننده می‌گرده و …

پیش نیاز)

به کتابخانه ای نیاز داریم که encoding زیرنویس‌ها رو تشخیص بده. متاسفانه سی شارپ خودش توی این زمینه ضعیفه و البته حقم داره هیچوقت نمیشه ۱۰۰٪ تشخیص داد. برای همین من از نسخه پورت شده uchardet استفاده می‌کنم که قبلا بهش اشاره کردم. بعدش این namespaces ها رو اضافه کنید که توی بقیه آموزش به مشکل بر نخورید.

حالا به تابعی برای تبدیل encoding ها به یکدیگه نیاز داریم که من مثال این آموزش رو استفاده کردم. بهتر تابع رو بالای برنامه تعریف کنید

شرح برنامه اصلی)

از ظاهر پروژه معلومه که windows form application استفاده کردم پس با حالت form_load میشه کشیدن و رها کردن رو شبیه سازی کرد:

تابع Form_DragEnter خیلی برای من مهم نیست. برای موقعی هست که فایل کشیده شده توی برنامه ولی هنوز رها نشده. فعلا فقط بررسی می‌کنه که نوع فایل مجاز باشه.

اما Form_DragDrop خیلی مهمه جایی هست که تمام تبدیل و تغییر اسم و … نوشته میشه پس هر چیزی که از اینجا به بعد می‌نویسم جای //process قرار می‌گیر.

خط اول یک آرایه درست می‌کنه از مسیر کامل فایل هایی که توی برنامه کشیده شدن.
خط دوم رو بر اساس فرمت‌های پشتیبانی شده توی KM PLAYER نوشتم خیلی هاش لازم نیست فقط MP4,MKV,FLV پر استفادست اکثرا.

بالا تر گفتم که فقط دوتا فایل کشیده میشه توی برنامه. پس طبیعتا یکی از گزینه ها ویدیو هست و دیگری زیرنویس؛ خط ۱۱ تا ۲۷ به ازای هر فرمتی که توی خط ۲ نوشته شده یک بار چک می‌کنه که ببینه ترتیب ویدیو و زیرنویس چطوریه کدومش اول اومده کدومش دوم و بعد مسیر و اسمش رو جدا می‌کنه.

اما خط ۵ تعداد فایل های درگ شده رو محاسبه می‌کنه مثلا میشه چک کرد کمتر از دوتا فایل خطا بگیره (بودنش در اصل الزامی نیست)

حالا قسمت نهایی کار یعنی تشخیص encoding و تبدیل اون به UTF-8 رو باید پیاده سازی کنیم:

کار ما با Form_DragDrop به پایان رسید؛ خط ۱-۶ فایل زیرنویس رو باز می‌کنه و بر اساس توابع تعریف شده در Ude کار تشخیص رو انجام میده. خط ۱۰ مهمه من توی تجربه قبلیم با این کتابخانه اشاره کردم که windows-1256 رو اشتباه تشخیص میده، این شرط برای تصحیح اون موقعیت هست.

خط ۱۵ همون تابع تبدیل encoding هست که آرگومان هاش به این صورته؛ مسیر مبدا – مسیر مقصد – فرمت مبدا – فرمت مقصد. اما اگر دقت کنید یک .tmp به انتهای آرگومان دوم اضافه کردم دلیلش اینه که فایل اصلی همچنان بازه و نمیشه هم encoding رو تغییر داد و هم اسمش رو با فایل ویدیو یکی کرد پس به یک فایل موقت نیاز داریم. خط ۱۷ فایل اصلی زیرنویس رو حذف می‌کنه و خط ۱۹ اسم فایل ویدیو رو روی فایل tmp که بالاتر ساخته شد قرار میده.

این برنامه در عین سادگیش کار راه اندازه، من سعی کردم فقط نکات کلیدی رو توضیح بدم که آموزش زیاد طولانی نشه مثلا میشه یک regex تعریف کرد که فصل و قسمت رو تشخیص بده اما این قانون ثابت نیست مترجم هرطوری که دلش بخواد فایل رو نامگذاری می‌کنه بنابر این من قرارداد رو اینطوری بستم که دوتا فایل بگیره که توی هر شرایطی جوابگو باشه. درضمن سورس برنامه به صورت یکجا روی gist قرار داره.

 

Author’s gravatar

خب روی سیستم اصلی هم از گنو لینوکس استفاده می‌کردی بهتر نبود ؟

Author’s gravatar

امان از دست تو :))
نه بهتر نبود. سیستمش گیمینگه و خب معلومه که اکثر بازی‌ها فقط برای ویندوز منتشر میشن.

نظری در این مورد دارید؟ خوشحال می‌شم اون رو برام ارسال کنید