سؤال

أرغب في فتح ملف فيديو صغير وتعيين كل الإطارات الموجودة في الذاكرة (لتطبيق بعض المرشحات المخصصة).لا أريد التعامل مع برنامج ترميز الفيديو، أفضل أن أترك المكتبة تتولى ذلك نيابةً عني.

لقد حاولت استخدام العرض المباشر مع مرشح SampleGrabber (باستخدام هذا النموذج http://msdn.microsoft.com/en-us/library/ms787867(VS.85).aspx)، لكنني تمكنت فقط من التقاط بعض الإطارات (وليس كل الإطارات!).أنا جديد تمامًا في برمجة برامج الفيديو، ربما لا أستخدم أفضل مكتبة، أو أفعل ذلك بشكل خاطئ.

لقد قمت بلصق جزء من الكود الخاص بي (بشكل رئيسي نسخة/لصق معدل من مثال msdn)، ولسوء الحظ لا يلتقط الإطارات الـ 25 الأولى كما هو متوقع...

[...]

hr = pGrabber->SetOneShot(TRUE);
hr = pGrabber->SetBufferSamples(TRUE);

pControl->Run(); // Run the graph.
pEvent->WaitForCompletion(INFINITE, &evCode); // Wait till it's done.

// Find the required buffer size.
long cbBuffer = 0;
hr = pGrabber->GetCurrentBuffer(&cbBuffer, NULL);

for( int i = 0 ; i < 25 ; ++i )
{
    pControl->Run(); // Run the graph.
    pEvent->WaitForCompletion(INFINITE, &evCode); // Wait till it's done.

    char *pBuffer = new char[cbBuffer];
    hr = pGrabber->GetCurrentBuffer(&cbBuffer, (long*)pBuffer);

    AM_MEDIA_TYPE mt;
    hr = pGrabber->GetConnectedMediaType(&mt);
    VIDEOINFOHEADER *pVih;
    pVih = (VIDEOINFOHEADER*)mt.pbFormat;

    [...]
}

[...]

هل هناك شخص لديه خبرة في برامج الفيديو يمكنه تقديم النصح لي بشأن الكود أو أي مكتبة أخرى أبسط؟

شكرًا

يحرر:يبدو أن روابط Msdn لا تعمل (رؤية الخلل)

هل كانت مفيدة؟

المحلول

حاليًا، هذه هي إطارات الفيديو الأكثر شيوعًا المتوفرة على منصات Win32:

  1. فيديو لنظام التشغيل Windows:يأتي إطار عمل Windows القديم من عصر Win95 ولكنه لا يزال مستخدمًا على نطاق واسع لأنه سهل الاستخدام للغاية.لسوء الحظ، فهو يدعم فقط ملفات AVI التي تم تثبيت برنامج ترميز VFW المناسب لها.

  2. عرض مباشر:إطار عمل WinXP القياسي، يمكنه بشكل أساسي تحميل جميع التنسيقات التي يمكنك تشغيلها باستخدام Windows Media Player.بل من الصعب استخدامها.

  3. فمبيغ:وبشكل أكثر دقة، libavcodec و libavformat الذي يأتي مع أداة الوسائط المتعددة مفتوحة المصدر Ffmpeg.إنه قوي للغاية ويمكنه قراءة الكثير من التنسيقات (تقريبًا كل ما يمكنك اللعب به سي.إل.سي) حتى لو لم يكن برنامج الترميز مثبتًا على النظام.إنه أمر معقد للغاية في الاستخدام ولكن يمكنك دائمًا الحصول على الإلهام من كود ffplay الذي يأتي مرفقًا به أو من خلال تطبيقات أخرى في البرامج مفتوحة المصدر.على أي حال، أعتقد أنه لا يزال أسهل بكثير في الاستخدام من DS (وأسرع بكثير).يجب أن يتم تجميعه بواسطة MinGW على نظام التشغيل Windows، ولكن تم شرح جميع الخطوات بشكل جيد للغاية هنا (في هذه اللحظة الرابط معطل، الأمل لم يمت).

  4. وقت سريع:لا يعد إطار عمل Apple هو الحل الأفضل لمنصة Windows، لأنه يحتاج إلى تثبيت تطبيق QuickTime وأيضًا برنامج ترميز QuickTime المناسب لكل تنسيق؛إنه لا يدعم العديد من التنسيقات، ولكنه شائع جدًا في المجال الاحترافي (لذا فإن بعض برامج الترميز مخصصة في الواقع لـ QuickTime فقط).لا ينبغي أن يكون من الصعب جدًا تنفيذها.

  5. Gstreamer:أحدث إطار مفتوح المصدر.لا أعرف الكثير عنها، وأعتقد أنها تلتف حول بعض الأنظمة الأخرى (لكنني لست متأكدًا).

تم تنفيذ كل هذه الأطر كواجهة خلفية في OpenCv Highgui، باستثناء DirectShow.يستخدم إطار العمل الافتراضي لـ Win32 OpenCV VFW (وبالتالي فهو قادر فقط على فتح بعض ملفات AVI)، إذا كنت تريد استخدام الملفات الأخرى، فيجب عليك تنزيل CVS بدلاً من الإصدار الرسمي مع الاستمرار في القيام ببعض القرصنة على الكود، وهو على أي حال ليس كذلك مكتمل جدًا، على سبيل المثال لا تسمح الواجهة الخلفية لـ FFMPEG بالبحث في الدفق.إذا كنت تريد استخدام QuickTime مع OpenCV هذا يستطيع مساعدتك.

نصائح أخرى

لقد استخدمت OpenCV لتحميل ملفات الفيديو ومعالجتها.كما أنه مفيد للعديد من أنواع معالجة الفيديو بما في ذلك تلك المفيدة لرؤية الكمبيوتر.

قد يمنحك استخدام نموذج "رد الاتصال" الخاص بـ SampleGrabber نتائج أفضل.راجع المثال في Samples\C++\DirectShow\Editing\GrabBitmaps.

هناك أيضًا الكثير من المعلومات في Samples\C++\DirectShow\Filters\Grabber2\grabber_text.txt وreadme.txt.

أعلم أنه من المغري جدًا في لغة C++ الحصول على تحليل مناسب لملفات الفيديو والقيام بذلك بنفسك.ولكن على الرغم من توفر المعلومات، إلا أنها عملية طويلة الأمد لبناء فئات لتسليم كل تنسيق ملف، وجعله قابلاً للتغيير بسهولة لأخذ التغييرات الهيكلية المستقبلية في الاعتبار، وبصراحة لا يستحق الأمر هذا الجهد.

بدلاً من ذلك أوصي بـ ffmpeg.لقد تم ذكره أعلاه، لكنه يقول أنه صعب، إنه ليس صعبًا.هناك خيارات أكثر بكثير مما قد يحتاجه معظم الناس مما يجعل الأمر يبدو أكثر صعوبة مما هو عليه بالفعل.بالنسبة لغالبية العمليات، يمكنك فقط السماح لـ ffmpeg بإنجاز الأمر بنفسه.

على سبيل المثال تحويل الملف FFMPEG -I inputFile.mp4 OutputFile.avi

قرر منذ البداية أنه سيتم تشغيل عمليات ffmpeg في سلسلة رسائل، أو بالأحرى مكتبة سلاسل رسائل.ولكن قم بتغليف فئة مؤشر الترابط الخاصة بك بحيث يمكنك الحصول على EventAgs الخاصة بك واكتملت طرق التحقق من مؤشر الترابط.شيء مثل :-

ThreadLibManager()
{
  List<MyThreads> listOfActiveThreads;
  public AddThread(MyThreads);
}
Your thread class is something like:-
class MyThread
{
 public Thread threadForThisInstance { get; set; }
 public MyFFMpegTools mpegTools { get; set; }
}
MyFFMpegTools performs many different video operations, so you want your own event  
args to tell your parent code precisely what type of operation has just raised and 
event.
enum MyFmpegArgs
{
public int thisThreadID { get; set; } //Set as a new MyThread is added to the List<>
public MyFfmpegType operationType {get; set;}
//output paths etc that the parent handler will need to find output files
}
enum MyFfmpegType
{
  FF_CONVERTFILE = 0, FF_CREATETHUMBNAIL, FF_EXTRACTFRAMES ...
}

فيما يلي مقتطف صغير من فئة أدوات ffmpeg الخاصة بي، وهذا الجزء يجمع معلومات حول مقطع فيديو.لقد قمت بوضع FFmpeg في مكان معين، وفي بداية تشغيل البرنامج يتم التأكد من وجوده هناك.بالنسبة لهذا الإصدار، قمت بنقله إلى سطح المكتب، وأنا متأكد تمامًا من أنني كتبت المسار بشكل صحيح لك (أنا حقًا أكره نظام المجلدات الخاصة لـ MS، لذا أتجاهله قدر الإمكان).

على أية حال، فهو مثال على استخدام ffmpeg بدون نوافذ.

        public string GetVideoInfo(FileInfo fi)
    {
        outputBuilder.Clear();
        string strCommand = string.Concat(" -i \"", fi.FullName, "\"");
        string ffPath =   
  System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\ffmpeg.exe";
        string oStr = "";

        try
        {
            Process build = new Process();
            //build.StartInfo.WorkingDirectory = @"dir";
            build.StartInfo.Arguments = strCommand;
            build.StartInfo.FileName = ffPath;

            build.StartInfo.UseShellExecute = false;
            build.StartInfo.RedirectStandardOutput = true;
            build.StartInfo.RedirectStandardError = true;
            build.StartInfo.CreateNoWindow = true;
            build.ErrorDataReceived += build_ErrorDataReceived;
            build.OutputDataReceived += build_ErrorDataReceived;
            build.EnableRaisingEvents = true;
            build.Start();
            build.BeginOutputReadLine();
            build.BeginErrorReadLine();
            build.WaitForExit();


            string findThis = "start";
            int offset = 0;
            foreach (string str in outputBuilder)
            {
                if (str.Contains("Duration"))
                {
                    offset = str.IndexOf(findThis);
                    oStr = str.Substring(0, offset);
                }
            }
        }
        catch
        {
            oStr = "Error collecting file information";
        }

        return oStr;
    }
    private void build_ErrorDataReceived(object sender, DataReceivedEventArgs e)
    {
        string strMessage = e.Data;
        if (outputBuilder != null && strMessage != null)
        {
            outputBuilder.Add(string.Concat(strMessage, "\n"));
        }
    } 

حاول استخدام OpenCV مكتبة.بالتأكيد لديه القدرات التي تحتاجها.

هذا الدليل يحتوي على قسم حول الوصول إلى الإطارات من ملف فيديو.

إذا كان الأمر يتعلق بملفات AVI، فسأقرأ البيانات من ملف AVI بنفسي واستخرج الإطارات.الآن استخدم مدير ضغط الفيديو لفك ضغطه.

تنسيق ملف AVI بسيط جدًا، راجع: http://msdn.microsoft.com/en-us/library/dd318187(VS.85).aspx (واستخدم جوجل).

بمجرد فتح الملف، ما عليك سوى استخراج كل إطار وتمريره إلى IDecompress() لفك ضغطه.

يبدو الأمر يتطلب الكثير من العمل ولكنها الطريقة الأكثر موثوقية.

إذا كان هذا يتطلب الكثير من العمل، أو إذا كنت تريد أكثر من ملفات AVI، فاستخدم ffmpeg.

يعد OpenCV هو الحل الأفضل إذا كان الفيديو في حالتك يحتاج فقط إلى أن يؤدي إلى سلسلة من الصور.إذا كنت على استعداد للقيام بمعالجة فيديو حقيقية، لذا فإن ViDeo يساوي "الصوت المرئي"، فأنت بحاجة إلى متابعة تلك التي يقدمها "martjno".تتضمن حلول Windows الجديدة أيضًا لـ Win7 3 إمكانيات جديدة بالإضافة إلى ذلك:

  1. مؤسسة ويندوز ميديا:خليفة DirectShow؛واجهة تنظيفها
  2. ويندوز ميديا ​​​​إنكودر 9:فهو لا يشمل البرنامج فحسب، بل يشحن أيضًا مكتبات للبرمجة
  3. تعبير ويندوز 4:خليفة 2.

الحلان الأخيران هما حلان تجاريان فقط، ولكن الحل الأول مجاني.لترميز WMF، تحتاج إلى تثبيت Windows SDK.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top