确定给定mp3文件的长度(以秒为单位)的最简单方法是什么,不使用外部库? (蟒蛇来源高度赞赏)
答案 0 :(得分:25)
您可以使用pymad。它是一个外部库,但不适用于Not Invented Here陷阱。你不想要任何外部库的任何特殊原因吗?
import mad
mf = mad.MadFile("foo.mp3")
track_length_in_milliseconds = mf.total_time()
发现here。
-
如果您真的不想使用外部库,请查看here并查看他是如何完成的。警告:这很复杂。
答案 1 :(得分:9)
对于谷歌粉丝来说,这里还有一些外部库:
mpg321 -t
ffmpeg -i
midentify(基本上是mplayer)请参阅Using mplayer to determine length of audio/video file
mencoder(传递它无效的params,它会吐出一条错误信息,但也会提供有关文件的信息,ex $ mencoder inputfile.mp3 -o fake)
mediainfo program http://mediainfo.sourceforge.net/en
exiftool
linux“file”命令
mp3info
SOX
参考文献: https://superuser.com/questions/36871/linux-command-line-utility-to-determine-mp3-bitrate
http://www.ruby-forum.com/topic/139468
(将其作为其他人添加的维基。)
和libs:.net:naudio,java:jlayer,c:libmad
干杯!
答案 2 :(得分:7)
简单,用Python解析MP3二进制blob来计算某些内容
这听起来像是一个非常高的订单。我不知道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;
}
答案 3 :(得分:6)
只需使用mutagen
$pip install mutagen
在python shell中使用它:
from mutagen.mp3 import MP3
audio = MP3(file_path)
print audio.info.length
答案 4 :(得分:3)
另外看一下audioread(包括ubuntu在内的一些Linux发行版都有包),https://github.com/sampsyo/audioread
audio = audioread.audio_open('/path/to/mp3')
print audio.channels, audio.samplerate, audio.duration
答案 5 :(得分:0)
您可以计算文件中的帧数。每个帧都有一个起始码,虽然我无法回想起起始码的确切值,但我没有MPEG规范。每帧具有一定的长度,对于MPEG1第二层约为40ms。
此方法适用于CBR文件(恒定比特率),VBR文件的工作方式完全不同。
从以下文件中:
对于第一层文件我们这个公式:
FrameLengthInBytes =(12 * BitRate / SampleRate + Padding)* 4
对于第二层和第二层III文件使用以下公式:
FrameLengthInBytes = 144 * BitRate / SampleRate + Padding