19

外部ライブラリを使用せずに、特定の mp3 ファイルの長さ (秒単位) を決定する最も簡単な方法は何ですか? (pythonソースは高く評価されています)

4

6 に答える 6

26

pymadを使用できます。これは外部ライブラリですが、Not Invented Here の罠にはまらないでください。外部ライブラリが不要な特定の理由はありますか?

import mad

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

ここで発見。

--

外部ライブラリを本当に使いたくない場合は、ここを見て、彼がどのようにそれを行ったかを確認してください。警告: 複雑です。

于 2008-09-23T06:37:50.947 に答える
10

Google フォロワーのために、さらにいくつかの外部ライブラリを次に示します。

mpg321 -t

ffmpeg -i

midentify (基本的には mplayer) mplayer を使用してオーディオ/ビデオ ファイルの長さを決定するを参照してください

mencoder (無効なパラメーターを渡すと、エラー メッセージが表示されますが、問題のファイルに関する情報も表示されます。例: $ mencoder inputfile.mp3 -o fake)

mediainfo プログラムhttp://mediainfo.sourceforge.net/en

exifツール

Linuxの「ファイル」コマンド

mp3情報

ソックス

参照: https://superuser.com/questions/36871/linux-command-line-utility-to-determine-mp3-bitrate

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

ミリ秒単位の mp3 の長さ

(これを他の人が追加できる wiki にします)。

およびライブラリ: .net: naudio、Java: jlayer、c: libmad

乾杯!

于 2011-02-20T18:49:58.853 に答える
8

PythonでMP3バイナリブロブを解析して何かを計算する

それはかなり難しい注文のように聞こえます。私は Python を知りませんが、これは私がかつて書こうとした別のプログラムからリファクタリングしたコードです。

注:これは C++ です (申し訳ありませんが、私が持っているものです)。また、そのままでは、固定ビット レートの MPEG 1 Audio Layer 3 ファイルのみを処理します。これで大部分をカバーできるはずですが、これがすべての状況で機能することを保証することはできません。うまくいけば、これで目的が達成され、Python にリファクタリングする方がゼロから行うよりも簡単です。

// 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;
}
于 2008-09-23T07:37:41.740 に答える
3

また、audioread (ubuntu を含む一部の Linux ディストリビューションにはパッケージがあります)、https://github.com/sampsyo/audioreadもご覧ください。

audio = audioread.audio_open('/path/to/mp3')
print audio.channels, audio.samplerate, audio.duration
于 2012-04-12T21:26:14.060 に答える
0

ファイル内のフレーム数を数えることができます。各フレームには開始コードがありますが、開始コードの正確な値を思い出すことはできず、MPEG の仕様もわかりません。各フレームには一定の長さがあり、MPEG1 レイヤー II では約 40ms です。

この方法は CBR ファイル (固定ビット レート) で機能しますが、VBR ファイルがどのように機能するかはまったく別の話です。

以下の文書から:

レイヤー I ファイルの場合、次の式を使用します。

FrameLengthInBytes = (12 * BitRate / SampleRate + パディング) * 4

レイヤ II および III ファイルの場合、次の式を使用します。

FrameLengthInBytes = 144 * BitRate / SampleRate + パディング

MPEG オーディオ フレーム ヘッダーに関する情報

于 2008-09-23T06:43:57.970 に答える