سؤال

ما هي أبسط طريقة لتحديد الطول (بالثواني) لملف mp3 معين، دون الاستعانة بمكتبات خارجية؟(مصدر بايثون موضع تقدير كبير)

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

المحلول

يمكنك استخدام pymad.إنها مكتبة خارجية، لكن لا تقع في فخ Not Invented Here.هل هناك سبب محدد لعدم رغبتك في أي مكتبات خارجية؟

import mad

mf = mad.MadFile("foo.mp3")
track_length_in_milliseconds = mf.total_time()    

مراقب هنا.

--

إذا كنت لا تريد حقًا استخدام مكتبة خارجية، فقم بإلقاء نظرة هنا وتحقق من كيف فعل ذلك.تحذير:انه لامر معقد.

نصائح أخرى

من أجل متابعي جوجل، إليك بعض الروابط الخارجية الإضافية:

mpg321 -ر

فمبيج -i

midentify (mplayer في الأساس) انظر استخدام mplayer لتحديد طول ملف الصوت/الفيديو

mencoder (قم بتمرير معلمات غير صالحة، وسوف تظهر رسالة خطأ ولكنها ستعطيك أيضًا معلومات حول الملف المعني، على سبيل المثال $ mencoder inputfile.mp3 -o fake)

برنامج معلومات الوسائط http://mediainfo.sourceforge.net/en

com.exiftool

أمر "ملف" لينكس

mp3info

سوكس

المراجع:https://superuser.com/questions/36871/linux-command-line-utility-to-determine-mp3-bitrate

http://www.ruby-forum.com/topic/139468

طول mp3 بالمللي ثانية

(جعل هذا موقع ويكي ليضيف إليه الآخرون).

و ليب:.شبكة:نوديو، جافا:جلاير، ج:libmad

هتافات!

تحليل ثنائي بسيط لملفات MP3 لحساب شيء ما في بايثون

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

ملحوظة: إنه مكتوب بلغة C++ (آسف، هذا ما لدي).وأيضًا، كما هو، سيتعامل فقط مع ملفات MPEG 1 Audio Layer 3 ذات معدل البت الثابت.الذي - التي يجب يغطي معظم الحالات، لكن لا يمكنني تقديم أي ضمان بخصوص نجاح هذا الأمر في جميع المواقف.نأمل أن يحقق هذا ما تريده، ونأمل أن تكون إعادة هيكلته إلى لغة بايثون أسهل من القيام بذلك من الصفر.

// determines the duration, in seconds, of an MP3;
// assumes MPEG 1 (not 2 or 2.5) Audio Layer 3 (not 1 or 2)
// constant bit rate (not variable)

#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;

//Bitrates, assuming MPEG 1 Audio Layer 3
const int bitrates[16] = {
         0,  32000,  40000,  48000,  56000,  64000,  80000,   96000,
    112000, 128000, 160000, 192000, 224000, 256000, 320000,       0
  };


//Intel processors are little-endian;
//search Google or see: http://en.wikipedia.org/wiki/Endian
int reverse(int i)
{
    int toReturn = 0;
    toReturn |= ((i & 0x000000FF) << 24);
    toReturn |= ((i & 0x0000FF00) << 8);
    toReturn |= ((i & 0x00FF0000) >> 8);
    toReturn |= ((i & 0xFF000000) >> 24);
    return toReturn;
}

//In short, data in ID3v2 tags are stored as
//"syncsafe integers". This is so the tag info
//isn't mistaken for audio data, and attempted to
//be "played". For more info, have fun Googling it.
int syncsafe(int i)
{
 int toReturn = 0;
 toReturn |= ((i & 0x7F000000) >> 24);
 toReturn |= ((i & 0x007F0000) >>  9);
 toReturn |= ((i & 0x00007F00) <<  6);
 toReturn |= ((i & 0x0000007F) << 21);
 return toReturn;     
}

//How much room does ID3 version 1 tag info
//take up at the end of this file (if any)?
int id3v1size(ifstream& infile)
{
   streampos savePos = infile.tellg(); 

   //get to 128 bytes from file end
   infile.seekg(0, ios::end);
   streampos length = infile.tellg() - (streampos)128;
   infile.seekg(length);

   int size;
   char buffer[3] = {0};
   infile.read(buffer, 3);
   if( buffer[0] == 'T' && buffer[1] == 'A' && buffer[2] == 'G' )
     size = 128; //found tag data
   else
     size = 0; //nothing there

   infile.seekg(savePos);

   return size;

}

//how much room does ID3 version 2 tag info
//take up at the beginning of this file (if any)
int id3v2size(ifstream& infile)
{
   streampos savePos = infile.tellg(); 
   infile.seekg(0, ios::beg);

   char buffer[6] = {0};
   infile.read(buffer, 6);
   if( buffer[0] != 'I' || buffer[1] != 'D' || buffer[2] != '3' )
   {   
       //no tag data
       infile.seekg(savePos);
       return 0;
   }

   int size = 0;
   infile.read(reinterpret_cast<char*>(&size), sizeof(size));
   size = syncsafe(size);

   infile.seekg(savePos);
   //"size" doesn't include the 10 byte ID3v2 header
   return size + 10;
}

int main(int argCount, char* argValues[])
{
  //you'll have to change this
  ifstream infile("C:/Music/Bush - Comedown.mp3", ios::binary);

  if(!infile.is_open())
  {
   infile.close();
   cout << "Error opening file" << endl;
   system("PAUSE");
   return 0;
  }

  //determine beginning and end of primary frame data (not ID3 tags)
  infile.seekg(0, ios::end);
  streampos dataEnd = infile.tellg();

  infile.seekg(0, ios::beg);
  streampos dataBegin = 0;

  dataEnd -= id3v1size(infile);
  dataBegin += id3v2size(infile);

  infile.seekg(dataBegin,ios::beg);

  //determine bitrate based on header for first frame of audio data
  int headerBytes = 0;
  infile.read(reinterpret_cast<char*>(&headerBytes),sizeof(headerBytes));

  headerBytes = reverse(headerBytes);
  int bitrate = bitrates[(int)((headerBytes >> 12) & 0xF)];

  //calculate duration, in seconds
  int duration = (dataEnd - dataBegin)/(bitrate/8);

  infile.close();

  //print duration in minutes : seconds
  cout << duration/60 << ":" << duration%60 << endl;

  system("PAUSE");
  return 0;
}

ببساطة استخدم mutagen

$pip install mutagen

استخدامه في بيثون شل:

from mutagen.mp3 import MP3
audio = MP3(file_path)
print audio.info.length

ألقِ نظرة أيضًا على القراءة الصوتية (تحتوي بعض توزيعات Linux بما في ذلك ubuntu على حزم)، https://github.com/sampsyo/audioread

audio = audioread.audio_open('/path/to/mp3')
print audio.channels, audio.samplerate, audio.duration

يمكنك حساب عدد الإطارات في الملف.يحتوي كل إطار على رمز بدء، على الرغم من أنني لا أستطيع تذكر القيمة الدقيقة لرمز البدء وليس لدي مواصفات MPEG.كل إطار له طول معين، حوالي 40 مللي ثانية لطبقة MPEG1 II.

تعمل هذه الطريقة مع ملفات CBR (معدل البت الثابت)، أما كيفية عمل ملفات VBR فهي قصة مختلفة تمامًا.

من الوثيقة أدناه:

بالنسبة للطبقة الأولى، فإننا نقدم هذه الصيغة:

FrameLengthInBytes = (12 * معدل البت / معدل العينات + الحشو) * 4

بالنسبة لملفات الطبقة الثانية والثالثة، استخدم هذه الصيغة:

FrameLengthInBytes = 144 * معدل البت / معدل العينات + الحشو

معلومات حول رأس إطار الصوت MPEG

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