





Вы можете использовать пимад. Это внешняя библиотека, но не попадайтесь в ловушку Not Invented Here. По какой причине вам не нужны внешние библиотеки?
import mad
mf = mad.MadFile("foo.mp3")
track_length_in_milliseconds = mf.total_time()
Обнаружил здесь.
-
Если вы действительно не хотите использовать внешнюю библиотеку, взгляните на здесь и посмотрите, как он это сделал. Предупреждение: это сложно.
Я согласен рекомендовать внешнюю библиотеку. Я не использовал его (или Python в этом отношении). Но однажды я попытался написать на C++ программу, которая могла бы просто проигрывать MP3. Это не сработало, но я смог определить продолжительность файла. Я думал о том, чтобы рефакторинг этого кода ...
... разместите здесь, но это чертовски запутанно. (И в C++, а не в Python). Даже отдаленно не простой.
Просто предупреждаю, мне кажется, что это работает только на определенных платформах. Самая последняя версия дает сбой при установке, потому что в ней отсутствует один из собственных установочных файлов, который я рекомендую сгенерировать, запустив второй файл с командами Linux в нем.
Вы можете посчитать количество кадров в файле. У каждого кадра есть начальный код, хотя я не могу вспомнить точное значение начального кода, и у меня нет спецификаций MPEG. Каждый кадр имеет определенную длину, около 40 мс для уровня II MPEG1.
Этот метод работает для CBR-файлов (Constant Bit Rate), как работают VBR-файлы - это совсем другая история.
Из документа ниже:
Для Layer I используется эта формула:
FrameLengthInBytes = (12 * BitRate / SampleRate + Padding) * 4
Для файлов Layer II и III используйте эту формулу:
FrameLengthInBytes = 144 * BitRate / SampleRate + Padding
Информация о заголовке аудиокадра MPEG
Я считаю, что длина составляет 26 мс.
Simple, parse MP3 binary blob to calculate something, in 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;
}
Это отлично работает для того, что я создаю прямо сейчас, поскольку мне не нужна поддержка VBR. Все, что мне нужно было изменить, это битрейт, поскольку он предполагал 56k, когда файлы были 32k (вывод LAME).
Ради последователей Google вот еще несколько внешних библиотек:
mpg321 -t
ffmpeg -i
midentify (в основном mplayer) см. Использование mplayer для определения длины аудио / видео файла
mencoder (передайте ему недопустимые параметры, он выдаст сообщение об ошибке, но также предоставит вам информацию о рассматриваемом файле, например $ mencoder inputfile.mp3 -o fake)
программа mediainfo 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
(сделать это вики для других).
и библиотеки: .net: naudio, java: jlayer, c: libmad
Ваше здоровье!
из этих ffmpeg и mpg321 также обрабатывают http-ссылки как местоположения файлов, к сожалению, последний автоматически воспроизводит файл, но я полностью доволен ffmpeg :)
Также взгляните на 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:
from mutagen.mp3 import MP3
audio = MP3(file_path)
print audio.info.length
Лучший ответ. Он легко устанавливается с помощью PIP, никаких других требований, и он просто предоставляет информацию, хранящуюся в метаданных файла.
откройте содержащую папку в проводнике, вызовите столбец времени воспроизведения, снимок экрана, ORC, текстовый поиск .... Отправить в The Daily WTF / шутка