基于lame对mp3进行分割的简单实现

一、思路:

利用lame编解码功能,在读取帧时检查下时间即可。

二、实现

1. 根据帧数计算时间:

static float

my_lame_get_current_time(const lame_global_flags *gfp,int frames)

{

int full  = lame_get_totalframes(gfp);

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;

return time_in_sec;

}

2. 检查时间

lame_encoder()负责编码,其流程是读取每一帧并进行编码。

写了个自己的lame_encoder(),加了两个参数start_time,end_time,

static int

my_lame_encoder(lame_global_flags * gf, FILE * outf, int nogap, char *inPath, char *outPath,float start_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。

static float

my_lame_get_current_time(const lame_global_flags *gfp,int frames)

{

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;

return time_in_sec;

}

static int

my_lame_encoder(lame_global_flags * gf, FILE * outf, int nogap, char *inPath, char *outPath,float start_time,floatend_time)

{

unsigned char mp3buffer[LAME_MAXMP3BUFFER];

int     Buffer[2][1152];

int     iread, imp3, owrite, id3v2_size;

int frame_count = 0;

int frame_total = 0;

float current_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

);

return 1;

}

owrite = (int) fwrite(mp3buffer, 1, imp3, outf);

if (owrite != imp3) {

encoder_progress_end(gf);

error_printf("Error writing ID3v2 tag \n");

return 1;

}

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);

return 1;

}

owrite = (int) fwrite(mp3buffer, 1, imp3, outf);

if (owrite != imp3) {

error_printf("Error writing mp3 output \n");

return 1;

}

}

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);

return 1;

}

encoder_progress_end(gf);

owrite = (int) fwrite(mp3buffer, 1, imp3, outf);

if (owrite != imp3) {

error_printf("Error writing mp3 output \n");

return 1;

}

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");

return 1;

}

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);

}

return 0;

}

int

main(int argc, 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_NOGAP 200

char    nogap_inPath_[MAX_NOGAP][PATH_MAX+1];

char*   nogap_inPath[MAX_NOGAP];

int     i;

FILE   *outf;

#if macintosh

argc = ccommand(&argv);

#endif

#if 0

/* 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> */

typedef BOOL(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();

return 1;

}

lame_set_errorf(gf, &frontend_errorf);

lame_set_debugf(gf, &frontend_debugf);

lame_set_msgf(gf, &frontend_msgf);

#if 0

if (argc <= 1) {

usage(stderr, argv[0]); /* no command-line args, print usage, exit  */

lame_close(gf);

frontend_close_console();

return 1;

}

#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();

return i;

}

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();

return ret;

}

基于lame对mp3进行分割的简单实现相关推荐

  1. CV之IS:利用pixellib库基于deeplabv3_xception模型对《庆余年》片段实现语义分割/图像分割简单代码全实现

    CV之IS:利用pixellib库基于deeplabv3_xception模型对<庆余年>片段实现语义分割/图像分割简单代码全实现 目录 利用pixellib库基于deeplabv3_xc ...

  2. android mp3 编码,Android 如何采用Lame编码器编码mp3文件

    这篇文章会基于下面3个问题来展开讲解. 1.什么是Lame? 2.为什么采用Lame? 3.Lame在Android应用上如何使用? 一.什么是Lame LAME is a high quality ...

  3. 基于 U-Net 的医学影像分割算法综述

    来源:UNknown知识库 转载自新机器视觉 仅做学术分享,若侵权,请联系删文 ▍一.医学图像分割简介 医学影像分割是医学影像分析中的重要领域,也是计算机辅助诊断.监视.干预和治疗所必需的一环,其关键 ...

  4. CVPR2021 | 基于transformer的视频实例分割网络VisTR

    原文:End-to-End Video Instance Segmentation with Transformers 翻译:夏初 摘要: 视频实例分割(VIS)是一项需要同时对视频中感兴趣的对象实例 ...

  5. 隆重介绍!一款新型基于姿势的人像实例分割框架

    全文共2493字,预计学习时长15分钟或更长 拍摄:Jezael Melgoza 来源:Unsplash 近年来,由于现实应用需求大,在计算机视觉领域有关"人"的研究层出不穷,实体 ...

  6. 基于网络音频的Android播放程序简单示例

    随着发布MP3文件.播客以及流式音频变得越来越受欢迎,构建可以利用这些服务的音频播放程序的需求也越来越强烈.幸运的是,Android拥有丰富的功能用于处理网络上存在的各种类型的音频. 1.基于HTTP ...

  7. 【深度学习】SETR:基于视觉 Transformer 的语义分割模型

    Visual Transformer Author:louwill Machine Learning Lab 自从Transformer在视觉领域大火之后,一系列下游视觉任务应用研究也随之多了起来.基 ...

  8. 基于libmad的MP3解码播放器

    libmad:是一个开源的高精度mpeg音频解码库,支持 MPEG-1(Layer I, Layer II 和 LayerIII(也就是 MP3).LIBMAD 提供 24-bit 的 PCM 输出, ...

  9. 笔记:基于DCNN的图像语义分割综述

    写在前面:一篇魏云超博士的综述论文,完整题目为<基于DCNN的图像语义分割综述>,在这里选择性摘抄和理解,以加深自己印象,同时达到对近年来图像语义分割历史学习和了解的目的,博古才能通今!感 ...

最新文章

  1. 大约 Apple Metal API 一些想法
  2. ros 中对一个点利用tf工具旋转,python or C++
  3. [转载]C#写的NoSQL开源项目/系统(系列)
  4. java非阻塞锁_Java并发问题的非阻塞解决方案
  5. 打印出数字字符串的偶位数
  6. 【Linux】基于Openfile的multipath测试
  7. 【NOIP2006】【Luogu1060】开心的金明(01背包模板)
  8. BGP(边界网关协议)
  9. 10 分钟实现 Spring Boot 发送邮件功能
  10. ubuntu下C语言打开bmp图像文件并读取数据
  11. oracle中DMP文件导入导出例子详解
  12. mysql load 忽略错误_mysql load data遇到的两个错误和解决方法
  13. Keil(MDK) 5 软件安装教程
  14. 【T+】T+和天联高级版软件结合使用的时候,运行T+提示网页崩溃了。
  15. 分段三次hermite插值python
  16. 【知识图谱】Neo4j 删除、清空数据库的方法
  17. 光缆接续盒图标_光缆线路施工技术(超全)
  18. 我用python给我的可爱小邻居做了一个猫狗识别系统~
  19. 学计算机专业可以做施工员吗,大龄转行做工程施工员,学起吃力吗?
  20. Mac下用docker安装阿波罗Apollo

热门文章

  1. NXP JN5169使用代码模板新建外设工程
  2. kmalloc使用不当导致内存分配失败问题
  3. 测试架构师必读:编码规范、开发技巧、架构画图
  4. LimeSDR USB 使用gqrx来收听FM广播
  5. mongodb near java_简阅MongoDB JVM开发库
  6. 无穷小量与无穷大量的阶
  7. uniapp百度身份证识别
  8. Scratch(三十七):串联电路
  9. win7 java修复工具哪个好_教您dll修复工具哪个好
  10. 自动取款机取款属于计算机应用,贵州电大2018年春季学期计算机应用基础01任务(含答案)...