read - reproduce audio python
duraciĆ³n de un archivo mp3 (6)
¿Cuál es la forma más simple de determinar la longitud (en segundos) de un archivo mp3 dado, sin usar bibliotecas externas ? (fuente python muy apreciada)
Simple, parse blob binario MP3 para calcular algo, en Python
Eso suena como una orden bastante difícil. No conozco Python, pero aquí hay un código que he refactorizado de otro programa que una vez intenté escribir.
Nota: Está en C ++ (lo siento, es lo que tengo). Además, tal como está, solo manejará archivos de MPEG 1 Audio Layer 3 de velocidad constante de bit. Eso debería cubrir la mayoría, pero no puedo garantizar que esto funcione en todas las situaciones. Esperemos que esto haga lo que quieras, y con suerte volver a convertirlo en Python es más fácil que hacerlo desde cero.
// 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;
}
Puede contar la cantidad de cuadros en el archivo. Cada cuadro tiene un código de inicio, aunque no puedo recordar el valor exacto del código de inicio y no tengo especificaciones MPEG por ahí. Cada cuadro tiene una cierta longitud, alrededor de 40 ms para MPEG1 capa II.
Este método funciona para archivos CBR (velocidad de bits constante), la forma en que funcionan los archivos VBR es una historia completamente diferente.
Del documento a continuación:
Para Layer I nos envía esta fórmula:
FrameLengthInBytes = (12 * BitRate / SampleRate + Padding) * 4
Para los archivos de Capa II y III use esta fórmula:
FrameLengthInBytes = 144 * BitRate / SampleRate + Padding
Puedes usar pymad . Es una biblioteca externa, pero no te enamores de la trampa Not Invented Here. ¿Alguna razón particular por la que no quieres bibliotecas externas?
import mad
mf = mad.MadFile("foo.mp3")
track_length_in_milliseconds = mf.total_time()
Visto aquí .
-
Si realmente no quieres usar una biblioteca externa, échale un vistazo aquí y mira cómo lo ha hecho. Advertencia: es complicado.
También eche un vistazo a audioread (algunas distribuciones de Linux incluyendo Ubuntu tienen paquetes), https://github.com/sampsyo/audioread
audio = audioread.audio_open(''/path/to/mp3'')
print audio.channels, audio.samplerate, audio.duration
simplemente use mutagen
$pip install mutagen
Úselo en el shell de Python:
from mutagen.mp3 import MP3
audio = MP3(file_path)
print audio.info.length
Para el bien de los seguidores de Google, aquí hay algunas librerías más externas:
mpg321 -t
ffmpeg -i
midentify (mplayer básicamente) vea Usar mplayer para determinar la longitud del archivo de audio / video
mencoder (le pasa los parámetros inválidos, escupirá un mensaje de error pero también le dará información sobre el archivo en cuestión, ex $ mencoder inputfile.mp3 -o fake)
programa mediainfo http://mediainfo.sourceforge.net/en
exiftool
el comando "archivo" de linux
mp3info
sox
refs: https://superuser.com/questions/36871/linux-command-line-utility-to-determine-mp3-bitrate
http://www.ruby-forum.com/topic/139468
longitud de mp3 en milisegundos
(haciendo de esto una wiki para que otros la agreguen).
y libs: .net: naudio, java: jlayer, c: libmad
¡Aclamaciones!