基于lame对mp3进行分割的简单实现
一、思路:
利用lame编解码功能,在读取帧时检查下时间即可。
二、实现
1. 根据帧数计算时间:
staticfloat
my_lame_get_current_time(constlame_global_flags *gfp,intframes)
{
intfull = lame_get_totalframes(gfp);
intfsize = lame_get_framesize(gfp);
intsrate = lame_get_out_samplerate(gfp);
floattime_in_sec = (float)frames;
time_in_sec *= fsize;
time_in_sec /= srate;
returntime_in_sec;
}
2. 检查时间
lame_encoder()负责编码,其流程是读取每一帧并进行编码。
写了个自己的lame_encoder(),加了两个参数start_time,end_time,
staticint
my_lame_encoder(lame_global_flags * gf, FILE * outf,intnogap,char*inPath,char*outPath,floatstart_time,floatend_time);
关键代码:
do{
/* read in 'iread' samples */
iread = get_audio(gf, Buffer);
frame_count++;
current_time = my_lame_get_current_time(gf,frame_count);
if( current_time<start_time )
continue;
if( current_time>end_time )
break;
...
}while(iread >0);
3. 时间参数处理
直接修改frontend/main.c,只接受mp3分割的参数。
3.1 参数处理:
if( argc !=5)
{
printf(
"lamecut 32bits version 0.99\n"
"\n"
"usage: lamecut infile outfile start_time end_time\n"
"\n"
"RECOMMENDED:\n"
" lame baby.mp3 baby1.mp3 15.605 17.734"
"\n"
);
exit(0);
}
strcpy(inPath,argv[1]);
strcpy(outPath,argv[2]);
sscanf( argv[3],"%f", &start_time);
sscanf( argv[4],"%f", &end_time);
input_format = sf_mp123;
注意:input_format 需要设为 sf_mp123;
3.2 调用my_lame_encoder,传入时间参数:
ret = my_lame_encoder( gf, outf,0, inPath, outPath, start_time, end_time );
三、代码
将frontend/main.c 中的main()函数去掉,再把以下代码拷贝到main.c,重新编译。
生成的lame即可用于分割mp3,建议改名为lamecut。
staticfloat
my_lame_get_current_time(constlame_global_flags *gfp,intframes)
{
int fsize = lame_get_framesize(gfp);
int srate = lame_get_out_samplerate(gfp);
float time_in_sec = (float)frames;
time_in_sec *= fsize;
time_in_sec /= srate;
returntime_in_sec;
}
staticint
my_lame_encoder(lame_global_flags * gf, FILE * outf,intnogap,char*inPath,char*outPath,floatstart_time,floatend_time)
{
unsignedcharmp3buffer[LAME_MAXMP3BUFFER];
int Buffer[2][1152];
int iread, imp3, owrite, id3v2_size;
intframe_count =0;
intframe_total =0;
floatcurrent_time =0.0f;
encoder_progress_begin(gf, inPath, outPath);
imp3 = lame_get_id3v2_tag(gf, mp3buffer,sizeof(mp3buffer));
if((size_t)imp3 >sizeof(mp3buffer)) {
encoder_progress_end(gf);
error_printf("Error writing ID3v2 tag: buffer too small: buffer size=%d ID3v2 size=%d\n"
,sizeof(mp3buffer)
, imp3
);
return1;
}
owrite = (int) fwrite(mp3buffer,1, imp3, outf);
if(owrite != imp3) {
encoder_progress_end(gf);
error_printf("Error writing ID3v2 tag \n");
return1;
}
if(flush_write ==1) {
fflush(outf);
}
id3v2_size = imp3;
/* encode until we hit eof */
do{
/* read in 'iread' samples */
iread = get_audio(gf, Buffer);
frame_count++;
current_time = my_lame_get_current_time(gf,frame_count);
if( current_time<start_time )
continue;
if( current_time>end_time )
break;
if(iread >=0) {
encoder_progress(gf);
/* encode */
imp3 = lame_encode_buffer_int(gf, Buffer[0], Buffer[1], iread,
mp3buffer,sizeof(mp3buffer));
/* was our output buffer big enough? */
if(imp3 <0) {
if(imp3 == -1)
error_printf("mp3 buffer is not big enough... \n");
else
error_printf("mp3 internal error: error code=%i\n", imp3);
return1;
}
owrite = (int) fwrite(mp3buffer,1, imp3, outf);
if(owrite != imp3) {
error_printf("Error writing mp3 output \n");
return1;
}
}
if(flush_write ==1) {
fflush(outf);
}
}while(iread >0);
frame_total = lame_get_totalframes(gf);
if(nogap)
imp3 = lame_encode_flush_nogap(gf, mp3buffer,sizeof(mp3buffer));/* may return one more mp3 frame */
else
imp3 = lame_encode_flush(gf, mp3buffer,sizeof(mp3buffer));/* may return one more mp3 frame */
if(imp3 <0) {
if(imp3 == -1)
error_printf("mp3 buffer is not big enough... \n");
else
error_printf("mp3 internal error: error code=%i\n", imp3);
return1;
}
encoder_progress_end(gf);
owrite = (int) fwrite(mp3buffer,1, imp3, outf);
if(owrite != imp3) {
error_printf("Error writing mp3 output \n");
return1;
}
if(flush_write ==1) {
fflush(outf);
}
imp3 = lame_get_id3v1_tag(gf, mp3buffer,sizeof(mp3buffer));
if((size_t)imp3 >sizeof(mp3buffer)) {
error_printf("Error writing ID3v1 tag: buffer too small: buffer size=%d ID3v1 size=%d\n"
,sizeof(mp3buffer)
, imp3
);
}
else{
if(imp3 >0) {
owrite = (int) fwrite(mp3buffer,1, imp3, outf);
if(owrite != imp3) {
error_printf("Error writing ID3v1 tag \n");
return1;
}
if(flush_write ==1) {
fflush(outf);
}
}
}
if(silent <=0) {
print_lame_tag_leading_info(gf);
}
if(fseek(outf, id3v2_size, SEEK_SET) !=0) {
error_printf("fatal error: can't update LAME-tag frame!\n");
}
else{
write_xing_frame(gf, outf);
}
if(silent <=0) {
print_trailing_info(gf);
}
return0;
}
int
main(intargc,char**argv)
{
int ret;
lame_global_flags *gf;
char outPath[PATH_MAX +1];
char inPath[PATH_MAX +1];
float start_time=0.0f;
float end_time=0.0f;
/* add variables for encoder delay/padding */
int enc_delay = -1;
int enc_padding = -1;
/* support for "nogap" encoding of up to 200 .wav files */
#define MAX_NOGAP200
char nogap_inPath_[MAX_NOGAP][PATH_MAX+1];
char* nogap_inPath[MAX_NOGAP];
int i;
FILE *outf;
#if macintosh
argc = ccommand(&argv);
#endif
#if0
/* rh 061207
the following fix seems to be a workaround for a problem in the
parent process calling LAME. It would be better to fix the broken
application => code disabled.
*/
#if defined(_WIN32)
/* set affinity back to all CPUs. Fix for EAC/lame on SMP systems from
"Todd Richmond" <todd.richmond@openwave.com> */
typedefBOOL(WINAPI * SPAMFunc) (HANDLE, DWORD_PTR);
SPAMFunc func;
SYSTEM_INFO si;
if((func = (SPAMFunc) GetProcAddress(GetModuleHandleW(L"KERNEL32.DLL"),
"SetProcessAffinityMask")) !=NULL) {
GetSystemInfo(&si);
func(GetCurrentProcess(), si.dwActiveProcessorMask);
}
#endif
#endif
#ifdef __EMX__
/* This gives wildcard expansion on Non-POSIX shells with OS/2 */
_wildcard(&argc, &argv);
#endif
memset(nogap_inPath_,0,sizeof(nogap_inPath_));
for(i =0; i < MAX_NOGAP; ++i) {
nogap_inPath[i] = &nogap_inPath_[i][0];
}
memset(inPath,0,sizeof(inPath));
frontend_open_console();
/* initialize libmp3lame */
input_format = sf_unknown;
if(NULL== (gf = lame_init())) {
error_printf("fatal error during initialization\n");
frontend_close_console();
return1;
}
lame_set_errorf(gf, &frontend_errorf);
lame_set_debugf(gf, &frontend_debugf);
lame_set_msgf(gf, &frontend_msgf);
#if0
if(argc <=1) {
usage(stderr, argv[0]);/* no command-line args, print usage, exit */
lame_close(gf);
frontend_close_console();
return1;
}
#endif
/* parse the command line arguments, setting various flags in the
* struct 'gf'. If you want to parse your own arguments,
* or call libmp3lame from a program which uses a GUI to set arguments,
* skip this call and set the values of interest in the gf struct.
* (see the file API and lame.h for documentation about these parameters)
*/
//parse_args_from_string(gf, getenv("LAMEOPT"), inPath, outPath);
//ret = parse_args(gf, argc, argv, inPath, outPath, nogap_inPath, &max_nogap);
if( argc !=5)
{
printf(
"lamecut 32bits version 0.99\n"
"\n"
"usage: lamecut infile outfile start_time end_time\n"
"\n"
"RECOMMENDED:\n"
" lame baby.mp3 baby1.mp3 15.605 17.734"
"\n"
);
exit(0);
}
strcpy(inPath,argv[1]);
strcpy(outPath,argv[2]);
sscanf( argv[3],"%f", &start_time);
sscanf( argv[4],"%f", &end_time);
input_format = sf_mp123;
if(update_interval <0.)
update_interval =2.;
outf = init_files(gf, inPath, outPath, &enc_delay, &enc_padding);
if(outf ==NULL) {
lame_close(gf);
frontend_close_console();
return-1;
}
/* turn off automatic writing of ID3 tag data into mp3 stream
* we have to call it before 'lame_init_params', because that
* function would spit out ID3v2 tag data.
*/
lame_set_write_id3tag_automatic(gf,0);
/* Now that all the options are set, lame needs to analyze them and
* set some more internal options and check for problems
*/
i = lame_init_params(gf);
if(i <0) {
if(i == -1) {
display_bitrates(stderr);
}
error_printf("fatal error during initialization\n");
lame_close(gf);
frontend_close_console();
returni;
}
if(silent >0) {
brhist =0; /* turn off VBR histogram */
}
/*
* encode a single input file
*/
brhist_init_package(gf);
//ret = lame_encoder(gf, outf, 0, inPath, outPath);
ret = my_lame_encoder( gf, outf,0, inPath, outPath, start_time, end_time );
fclose(outf);/* close the output file */
close_infile();/* close the input file */
lame_close(gf);
frontend_close_console();
returnret;
}
分享到:
相关推荐
利用开源的lame库做的mp3编码解码程序.
mp3编码解码器lame源代码,,可实现mp3与wave文件的互相转换
基于Lame库实现的NDK层调用,供Android App将PCM、WAV、AIFF等音频格式转为MP3格式文件的案例
很好的IOS录音,基于lame实现边转边录音,由caf格式转换成mp3格式
lame-MP3编码器exe及dll文件
使用lame库将pcm编码成mp3文件,使用Android Studio 新版,Cmake管理。
Lame MP3编码器,用于MP3压缩,编码,效果超好
LAME(MP3压缩引擎) 绿色汉化版 V3.98
Lame想必大家都知道,这个就是为了方便实用,套上了一个GUI,其实核心都是一样的~
LAME3.92经典MP3编码器 -b 320 -q 3 --noath -k LAME3.92经典MP3编码器 -b 320 -q 3 --noath -k
最好的MP3转换软件,非常好用!希望大家都能喜欢!
foobar转换mp3插件lame.exe
Lame,录音的raw格式转为mp3格式的工具
可在程序中自动调用lame进行音频格式的转换,如mp3转wav格式,wav格式转换成MP3格式,前提是将lame.exe放在自己的工程目录下,这里lame也一并提供
在对MP3快要失望时,Lame从天而降,我抱着怀疑的态度试用了她,结果令人惊讶不已,立刻删除了硬盘上所有的MP3和其他编码器,全部用Lame重新来过。这个是Lame的最新版,有着不小的改进,你会在使用中发现。
用Lame编码器把WAV转成MP3. http://lame.sourceforge.net/上的编码器,在delphi7上实现,官方自带的MP3export.pas文件有问题,这是我修改之后,测试可用。
详细讲解请参考:http://blog.csdn.net/allen315410/article/details/42456661
用于音频的转换,适用于iOS,将.caf文件转换为.MP3文件
lame 公司的MP3 编码器,可以学习一下!