基于lame对mp3进行分割的简单实现
基于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进行分割的简单实现相关推荐
- CV之IS:利用pixellib库基于deeplabv3_xception模型对《庆余年》片段实现语义分割/图像分割简单代码全实现
CV之IS:利用pixellib库基于deeplabv3_xception模型对<庆余年>片段实现语义分割/图像分割简单代码全实现 目录 利用pixellib库基于deeplabv3_xc ...
- android mp3 编码,Android 如何采用Lame编码器编码mp3文件
这篇文章会基于下面3个问题来展开讲解. 1.什么是Lame? 2.为什么采用Lame? 3.Lame在Android应用上如何使用? 一.什么是Lame LAME is a high quality ...
- 基于 U-Net 的医学影像分割算法综述
来源:UNknown知识库 转载自新机器视觉 仅做学术分享,若侵权,请联系删文 ▍一.医学图像分割简介 医学影像分割是医学影像分析中的重要领域,也是计算机辅助诊断.监视.干预和治疗所必需的一环,其关键 ...
- CVPR2021 | 基于transformer的视频实例分割网络VisTR
原文:End-to-End Video Instance Segmentation with Transformers 翻译:夏初 摘要: 视频实例分割(VIS)是一项需要同时对视频中感兴趣的对象实例 ...
- 隆重介绍!一款新型基于姿势的人像实例分割框架
全文共2493字,预计学习时长15分钟或更长 拍摄:Jezael Melgoza 来源:Unsplash 近年来,由于现实应用需求大,在计算机视觉领域有关"人"的研究层出不穷,实体 ...
- 基于网络音频的Android播放程序简单示例
随着发布MP3文件.播客以及流式音频变得越来越受欢迎,构建可以利用这些服务的音频播放程序的需求也越来越强烈.幸运的是,Android拥有丰富的功能用于处理网络上存在的各种类型的音频. 1.基于HTTP ...
- 【深度学习】SETR:基于视觉 Transformer 的语义分割模型
Visual Transformer Author:louwill Machine Learning Lab 自从Transformer在视觉领域大火之后,一系列下游视觉任务应用研究也随之多了起来.基 ...
- 基于libmad的MP3解码播放器
libmad:是一个开源的高精度mpeg音频解码库,支持 MPEG-1(Layer I, Layer II 和 LayerIII(也就是 MP3).LIBMAD 提供 24-bit 的 PCM 输出, ...
- 笔记:基于DCNN的图像语义分割综述
写在前面:一篇魏云超博士的综述论文,完整题目为<基于DCNN的图像语义分割综述>,在这里选择性摘抄和理解,以加深自己印象,同时达到对近年来图像语义分割历史学习和了解的目的,博古才能通今!感 ...
最新文章
- 大约 Apple Metal API 一些想法
- ros 中对一个点利用tf工具旋转,python or C++
- [转载]C#写的NoSQL开源项目/系统(系列)
- java非阻塞锁_Java并发问题的非阻塞解决方案
- 打印出数字字符串的偶位数
- 【Linux】基于Openfile的multipath测试
- 【NOIP2006】【Luogu1060】开心的金明(01背包模板)
- BGP(边界网关协议)
- 10 分钟实现 Spring Boot 发送邮件功能
- ubuntu下C语言打开bmp图像文件并读取数据
- oracle中DMP文件导入导出例子详解
- mysql load 忽略错误_mysql load data遇到的两个错误和解决方法
- Keil(MDK) 5 软件安装教程
- 【T+】T+和天联高级版软件结合使用的时候,运行T+提示网页崩溃了。
- 分段三次hermite插值python
- 【知识图谱】Neo4j 删除、清空数据库的方法
- 光缆接续盒图标_光缆线路施工技术(超全)
- 我用python给我的可爱小邻居做了一个猫狗识别系统~
- 学计算机专业可以做施工员吗,大龄转行做工程施工员,学起吃力吗?
- Mac下用docker安装阿波罗Apollo