mp3文件的时间长度

问题描述:

什么是最简单的方法来确定给定的MP3文件的长度(以秒为单位),而不使用外部库? (蟒蛇源高度赞赏)mp3文件的时间长度

+5

在资源管理器中打开包含文件夹调出播放时间栏,屏幕显示t,ORC,文本搜索....提交给每日跆拳道/笑话 – BCS 2008-09-23 06:35:41

您可以使用pymad。这是一个外部图书馆,但不要落入这个不发明的陷阱。任何特定的原因你不想要任何外部库?

import mad 

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

发现here

-

如果你真的不想使用外部库,看看here,并检查了他是怎么做到的。警告:这很复杂。

+0

我同意推荐外部图书馆。我没有用过它(或者Python)。但我曾经试着用C++写一个可以简单播放MP3的程序。这并没有出现,但我确定了足够的时间来确定文件的持续时间。我想过重构该代码... – 2008-09-23 06:50:32

+0

...在这里发布,但它是相当复杂的。 (而在C++中,不是Python)。甚至不是很简单。 – 2008-09-23 06:52:21

+1

只是抬头,它看起来像它只能在某些平台上工作。最新的版本在安装时崩溃,因为它缺少自己的安装文件之一,它建议我通过运行第二个带有linux命令的文件来生成它。 – 2015-03-15 00:35:53

您可以计算文件中的帧数。每个帧都有一个起始码,尽管我无法回忆起始码的确切值,也没有MPEG规格。每个帧都有一定的长度,对于MPEG1 II层大约为40ms。

这种方法适用于CBR文件(恒定比特率),VBR文件如何工作是一个完全不同的故事。

从下面的文件:

对于层I文件我们这个公式:

FrameLengthInBytes =(12 *比特率/采样率+填充)* 4

用于层II & III文件使用这式:

FrameLengthInBytes = 144 *码率/采样率+填充

Information about MPEG Audio Frame Header

+0

我相信这个长度是26ms。 – 2009-02-27 21:36:34

+0

听起来很熟悉。 – 2009-03-05 12:43:22

简单,分析MP3二进制BLOB计算的东西,在Python

这听起来像一个非常艰巨的任务。我不知道Python,但是这里有一些代码是我从另一个我曾经写过的程序中重构而来的。

注:这是在C++(对不起,这是我的)。而且,它现在只能处理恒定比特率的MPEG 1音频层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; 
} 

对于谷歌的追随者的缘故,这里有一些更多的外部库:

mpg321 -t

的ffmpeg -i

midentify(mplayer的基本)看到Using mplayer to determine length of audio/video file

mencoder(通过它无效的参数,它会吐出一个错误消息,但也给你的信息在问题上的文件,前$ mencoder inputfile.mp3 -o假)

的MediaInfo程序http://mediainfo.sourceforge.net/en

exiftool

在linux “文件” 命令

mp3info

SOX

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

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

mp3 length in milliseconds

(使这个为他人维基添加到)。

和库:.NET:n音讯,JAVA:jlayer,C:的libmad

干杯!

而且看看audioread(一些Linux发行版包括Ubuntu有包),https://github.com/sampsyo/audioread

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

只需使用mutagen

$pip install mutagen 

使用它在Python Shell:

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