2008-09-23 2 views
16

Каков самый простой способ определить длину (в секундах) данного mp3-файла, без использования внешних библиотек? (источник python высоко оценивается)длина времени mp3-файла

+5

откройте содержащую папку в проводнике, введите столбец времени воспроизведения, экран sho t, ORC, текстовый поиск .... Отправить в Daily WTF/joke – BCS 2008-09-23 06:35:41

ответ

24

Вы можете использовать pymad. Это внешняя библиотека, но не попадайте в ловушку Not Invented Here. Любая конкретная причина, по которой вам не нужны внешние библиотеки?

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

0

Вы можете рассчитывать количество кадров в файле. Каждый кадр имеет начальный код, хотя я не могу вспомнить точное значение стартового кода, и у меня нет спецификации MPEG. Каждый кадр имеет определенную длину, около 40 мс для слоя MPEG1 II.

Этот метод работает для CBR-файлов (постоянная скорость передачи), как работает VBR-файлы - это совершенно другая история.

С ниже документа:

Для слоя I Files нам эту формулу:

FrameLengthInBytes = (12 * битрейта/SampleRate + Набивка) * 4

Для слоя II & III файлы используют этот формула:

FrameLengthInBytes = 144 * битрейта/SampleRate + Набивка

Information about MPEG Audio Frame Header

+0

Я считаю, что длина составляет 26 мс. – 2009-02-27 21:36:34

+0

Звучит знакомо. – 2009-03-05 12:43:22

8

Простой, синтаксический MP3 блоб вычислить что-то в Python

Это звучит как довольно высокий порядок. Я не знаю 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; 
} 
9

Ради Google последователей, вот еще несколько внешних ЛИЭС:

mpg321 -t

FFmpeg -i

midentify (MPlayer в основном) см Using mplayer to determine length of audio/video file

mencoder (передайте ему недействительные параметры, он выплюнет сообщение об ошибке, но также предоставит вам информацию о файле, о котором идет речь, ex $ mencoder inputfile.mp3 -o fake)

MediaInfo программа http://mediainfo.sourceforge.net/en

ExifTool

"Файл" линукс команда

mp3info

сокс

рефов: 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: NAudio, Java: jlayer, с: libmad

Ура!

3

Также обратите внимание на audioread (некоторые Linux дистрибутивы, включая Ubuntu есть пакеты), https://github.com/sampsyo/audioread

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

просто использовать mutagen

$pip install mutagen 

использовать его в оболочке Python:

from mutagen.mp3 import MP3 
audio = MP3(file_path) 
print audio.info.length 
Смежные вопросы