ffmpeg تحميل - اقتطع MP3 إلى أول 30 ثانية




برنامج lame (10)

لقد حصلت على خطأ أثناء القيام بنفس الشيء

Invalid audio stream. Exactly one MP3 audio stream is required.
Could not write header for output file #0 (incorrect codec parameters     ?): Invalid argumentStream mapping:

إصلاح بالنسبة لي كان: ffmpeg -ss 00: 02: 43.00 -t 00:00:10 -i input.mp3 -codec: a libmp3lame out.mp3

السؤال الأصلي

أريد أن أكون قادرًا على إنشاء ملف MP3 جديد (صحيح تمامًا) من ملف MP3 موجود لاستخدامه كأسلوب معاينة - محاولة قبل الشراء. يجب أن يحتوي الملف الجديد فقط على أول ثانية من المسار.

الآن ، أعلم أنه يمكنني فقط "قطع التيار" في n ثانية (حساب من معدل البت وحجم الرأس) عند تسليم الملف ، ولكن هذا هو قليلا القذرة و PITA حقيقية على مسار VBR. أود أن أتمكن من إنشاء ملف MP3 مناسب.

أي شخص أي أفكار؟

الأجوبة

كل من mp3split و ffmpeg كلاهما حلول جيدة. اخترت ffmpeg كما هو مثبت بشكل شائع على خوادم لينكس وأيضا متاحة بسهولة للنوافذ . هنا بعض معلمات سطر الأوامر الجيدة لإنشاء معاينات مع ffmpeg

  • -t <seconds> قطع بعد عدد محدد من الثواني
  • -y ملف قوة الكتابة
  • -ab <bitrate> تعيين معدل البت على سبيل المثال -ab 96k
  • -ar <rate Hz> تعيين معدل أخذ العينات على سبيل المثال -ar 22050 لـ 22.05 كيلو هرتز
  • -map_meta_data <outfile>:<infile> نسخ بيانات تعريف المسار من infile إلى outfile

بدلاً من الإعداد -ab و -ar ، يمكنك نسخ إعدادات المسار الأصلية ، كما يقترح تيم فارلي ، مع:

  • -acodec copy

مجرد فكرة: قد ترغب في تخطي بداية الأغنية الأصلية. لنقل ، يمكنك استخدام 30 ثانية قطعة تبدأ من ثلث الأغنية.
في بعض الأغاني ، لا تخبرك أول 30 ثانية بقدر ما أنها جزء من "إعداد المشهد" - على سبيل المثال بينك فلويد " Shine On You Crazy Diamond" .


فقط كما لاحظت ، كان لدي وقت سيء حقا مع ffmpeg ، mptsplit و mp3cutter على CentOS ، كلهم ​​يبلغون عن "عنوان مفقود". لذلك ، اضطررت للذهاب مع فئة MP3 وبعض الرياضيات لقطع عن طريق الملفات.


لم أستخدمها لهذا الغرض المحدد ، لكنني أراهن على أن ffmpeg تستطيع فعل ذلك.


كما أوصي ffmpeg ، لكن سطر الأوامر الذي اقترحه John Boker له تأثير جانبي غير مقصود: فهو يعيد تشفير الملف إلى معدل البت الافتراضي (وهو 64 كيلوبت / ثانية في الإصدار الذي أستخدمه هنا على الأقل). قد يمنح ذلك لعملائك انطباعًا خاطئًا عن جودة ملفات الصوت ، ويستغرق أيضًا وقتًا أطول.

في ما يلي سطر أوامر سيتم تقطيعه إلى 30 ثانية دون تحويل الشفرة:

ffmpeg -t 30 -i inputfile.mp3 -acodec copy outputfile.mp3

يقوم رمز التبديل -acodec بإعلام ffmpeg باستخدام برنامج الترميز "copy" الخاص الذي لا يتم تحويله. إنه سريع بسرعة.

ملاحظة: تم تحديث الأمر بناء على تعليق من Oben Sonne


لقد استخدمت هذا: Mp3Splt قبل مع نتائج جيدة


يمكنك استخدام mp3cut:

cutmp3 -i foo.mp3 -O 30s.mp3 -a 0:00.0 -b 0:30.0

انها في ريبو أوبونتو ، لذلك فقط: sudo apt-get install cutmp3 .


إذا كنت ترغب في إزالة أول 30 ثانية (والاحتفاظ بالباقي) ، فاستخدم هذا:

ffmpeg -ss 30 -i inputfile.mp3 -acodec copy outputfile.mp3

قد ترغب في محاولة Mp3Splt .

لقد استعملته من قبل في خدمة C # التي ملفوفة ببساطة عملية win32 mp3splt.exe. أفترض أن شيئًا مشابهًا يمكن تنفيذه في سيناريو Linux / PHP.


بعد إجراء بعض التحقيقات ، تمكنت من تنفيذ فك تشفير HW الضروري على نظامي التشغيل X (VDA) و Linux (VDPAU). سوف أقوم بتحديث الإجابة عندما أتلقى تطبيق Windows أيضًا. لذلك دعونا نبدأ مع أسهل:

نظام التشغيل Mac OS X

للحصول على تسريع HW على نظام التشغيل Mac OS ، يجب عليك فقط استخدام ما يلي: avcodec_find_decoder_by_name("h264_vda"); لاحظ أنه مع ذلك يمكنك تسريع مقاطع الفيديو h264 فقط على نظام التشغيل Mac OS مع FFmpeg.

لينكس VDPAU

في نظام Linux ، تكون الأمور أكثر تعقيدًا (من المفاجئ؟). يحتوي FFmpeg على مسرعات 2 HW على Linux: VDPAU (Nvidia) و VAAPI (Intel) وفك تشفير واحد فقط HW: من أجل VDPAU. وقد يبدو من المعقول تمامًا استخدام وحدة فك ترميز vdpau كما في مثال Mac OS أعلاه: avcodec_find_decoder_by_name("h264_vdpau");

قد تتفاجأ بمعرفة أنه لا يغير شيئًا وليس لديك تسارع على الإطلاق. ذلك لأنه ليس سوى البداية ، يجب عليك كتابة المزيد من التعليمات البرمجية للحصول على تسريع العمل. لحسن الحظ ، ليس عليك أن تتوصل إلى حل بمفردك: يوجد على الأقل مثالان جيدان على كيفية تحقيق ذلك: libavg و FFmpeg نفسها. لدى libavg فئة VDPAUDecoder والتي هي واضحة تمامًا والتي تستند إلى تنفيذها. يمكنك أيضًا الرجوع إلى ffmpeg_vdpau.c للحصول على تطبيق آخر للمقارنة. في رأيي فإن تطبيق libavg أسهل في الفهم.

الأشياء الوحيدة التي تفتقر إليها الأمثلة المذكورة أعلاه هي النسخ الصحيح للإطار الذي تم فك تشفيره إلى الذاكرة الرئيسية. يستخدم كلا المثالين VdpVideoSurfaceGetBitsYCbCr مما أدى إلى مقتل كل الأداء الذي اكتسبته على الجهاز. لهذا السبب قد ترغب في استخدام الإجراء التالي لاستخراج البيانات من وحدة معالجة الرسومات:

bool VdpauDecoder::fillFrameWithData(AVCodecContext* context,
    AVFrame* frame)
{
    VdpauDecoder* vdpauDecoder = static_cast<VdpauDecoder*>(context->opaque);
    VdpOutputSurface surface;
    vdp_output_surface_create(m_VdpDevice, VDP_RGBA_FORMAT_B8G8R8A8, frame->width, frame->height, &surface);
    auto renderState = reinterpret_cast<vdpau_render_state*>(frame->data[0]);
    VdpVideoSurface videoSurface = renderState->surface;

    auto status = vdp_video_mixer_render(vdpauDecoder->m_VdpMixer,
        VDP_INVALID_HANDLE,
        nullptr,
        VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME,
        0, nullptr,
        videoSurface,
        0, nullptr,
        nullptr,
        surface,
        nullptr, nullptr, 0, nullptr);
    if(status == VDP_STATUS_OK)
    {
        auto tmframe = av_frame_alloc();
        tmframe->format = AV_PIX_FMT_BGRA;
        tmframe->width = frame->width;
        tmframe->height = frame->height;
        if(av_frame_get_buffer(tmframe, 32) >= 0)
        {
            VdpStatus status = vdp_output_surface_get_bits_native(surface, nullptr,
                reinterpret_cast<void * const *>(tmframe->data),
                reinterpret_cast<const uint32_t *>(tmframe->linesize));
            if(status == VDP_STATUS_OK && av_frame_copy_props(tmframe, frame) == 0)
            {
                av_frame_unref(frame);
                av_frame_move_ref(frame, tmframe);
                return;
            }
        }
        av_frame_unref(tmframe);
    }
    vdp_output_surface_destroy(surface);
    return 0;
}

على الرغم من أنه يحتوي على بعض الكائنات "الخارجية" المستخدمة في داخلك ، إلا أنه يجب أن تكون قادرًا على فهمها بمجرد قيامك بتنفيذ جزء "الحصول على المخزن المؤقت" (حيث الأمثلة المذكورة أعلاه ذات مساعدة كبيرة). كما أنني استخدمت تنسيق BGRA الذي كان أكثر ملاءمة لاحتياجاتي وربما اخترت آخر.

تكمن المشكلة في كل ذلك في أنه لا يمكنك فقط تشغيله من FFmpeg التي تحتاجها لفهم أساسيات واجهة برمجة تطبيقات VDPAU على الأقل. وآمل أن تساعد إجابتي شخصًا ما في تطبيق تسريع HW على Linux. لقد قضيت الكثير من الوقت في ذلك بنفسي قبل أن أدرك أنه لا توجد طريقة بسيطة من سطر واحد لتطبيق فك التشفير المتسارع على نظام Linux.

Linux VA-API

نظرًا لأن سؤالي الأصلي كان يتعلق بـ VA-API ، لا يمكنني تركه بدون إجابة. بادئ ذي avcodec_find_decoder_by_name("h264_vaapi") لا يوجد أي وحدة فك ترميز لـ VA-API في FFmpeg ، لذلك فإن avcodec_find_decoder_by_name("h264_vaapi") لا معنى له: إنه nullptr . لا أعرف كم هو أصعب (أو ربما أكثر بساطة؟) تطبيق فك التشفير عبر VA-API لأن جميع الأمثلة التي رأيتها كانت مخيفة للغاية. لذلك اخترت عدم استخدام VA-API على الإطلاق واضطررت إلى تطبيق تسريع بطاقة Intel. لحسن الحظ كافية بالنسبة لي ، هناك مكتبة VDPAU (برنامج التشغيل؟) والتي تعمل على VA-API. حتى تتمكن من استخدام VDPAU على بطاقات Intel!

لقد استخدمت link التالي لإعداده على جهاز Ubuntu الخاص بي.

أيضًا ، قد ترغب في مراجعة التعليقات على السؤال الأصلي حيث ذكرTimothy_G أيضًا بعض الروابط المتعلقة بـ VA-API.