2013-12-20 115 views
6

我有一个很大的声音文件(150 MB),我想将它分割为一些更容易管理的大小的较小文件,例如带有5分钟音频的文件。显然,最后一部分将是< = 5分钟,没关系。有没有办法轻松完成这种任务?将音频文件分割成任意大小的片段

可以使用此链接下载用于此问题的小示例.mp3文件:download.linnrecords.com/test/mp3/recit.aspx。

这是我到目前为止尝试过的。我从tuneR使用readMP3导入数据,并打算使用cutw函数,但尚未找到使用它的有效方法。

library(tuneR) 

sample<-readMP3("recit.mp3") 

# the file is only 9.04 seconds long (44.1 Hz, 16-bit, sterio) 
# so, for this example we can cut it into 0.5 second intervals) 
subsamp1<-cutw(sample, from=0, to=0.5, output="Wave") 

# then I would have to do this for each interval up to: 
subsampn<-cutw(sample, from=9, to=9.04, output="Wave") 
# where I have to explicitly state the maximum second (i.e. 9.04), 
# unless there is a way I don't know of to extract this information. 

这种方法是低效的,当间隔相比,在总文件长度变小。另外,sample是立体声,但subsamp1是单声道的,如果可能,我不希望更改任何有关数据的内容。

在提高效率的方式中,我尝试了向fromto参数输入矢量,但是出现错误(请参阅下文)。尽管它已经有效,但它不是一个特别好的解决方案。任何人都知道使用R来解决这个问题的更优雅的方式?

cutw(subsamp1,from=seq(0,9,0.5),to=c(seq(0.5,9.0,0.5),9.04) 
# had to explicitly supply the max second (i.e. 9.04). 
# must be a better way to extract the maximum second 

Error in wave[a:b, ] : subscript out of bounds 
In addition: Warning messages: 
1: In if (from > to) stop("'from' cannot be superior to 'to'") : 
    the condition has length > 1 and only the first element will be used 
2: In if (from == 0) { : 
    the condition has length > 1 and only the first element will be used 
3: In a:b : numerical expression has 19 elements: only the first used 
+0

你可以看看到'mapply' – Dason

+0

不,但它会b方便这类问题。 – Dason

回答

2

我没有任何使用R语言处理音频文件的经验,但是我能够想出一个可能对您有帮助的方法。看看下面的代码。由@Jean V.亚当斯优异答案

library(seewave) 

# your audio file (using example file from seewave package) 
data(tico) 
audio <- tico 
# the frequency of your audio file 
freq <- 22050 
# the length and duration of your audio file 
totlen <- length(audio) 
totsec <- totlen/freq 

# the duration that you want to chop the file into 
seglen <- 0.5 

# defining the break points 
breaks <- unique(c(seq(0, totsec, seglen), totsec)) 
index <- 1:(length(breaks)-1) 
# a list of all the segments 
subsamps <- lapply(index, function(i) cutw(audio, f=freq, from=breaks[i], to=breaks[i+1])) 
3

大厦,我发现使用索引(即[)中的溶液。

library(seewave) 

# your audio file (using example file from seewave package) 
data(tico) 
audio <- tico 
# the frequency of your audio file 
freq <- 22050 
# the length and duration of your audio file 
totlen <- length(audio) 
totsec <- totlen/freq 

# the duration that you want to chop the file into 
seglen <- 0.5 

# defining the break points 
breaks <- unique(c(seq(0, totsec, seglen), totsec)) 
index <- 1:(length(breaks)-1) 
# a list of all the segments 
lapply(index, function(i) audio[(breaks[i]*freq):(breaks[i+1]*freq)]) 
# the above final line is the only difference between this code and the 
# code provided by @Jean V. Adams 

这里的优点是,如果您的输入音频对象是立体声,返回的对象也是立体声。从我所知道的,cutw将输出对象更改为单声道。

+0

看起来像你自己解决了立体声/单声道问题。尼斯。 –

0

检查https://github.com/schultzm/SliceAudio.py 我写了这个脚本来做一个非常相似的事情,就像在这个问题中提出的那样,但是我用python写了这个脚本。不知道它是否仍然相关,但无论如何这都是我的解决方案。如果需要,您可以从R内启动Python脚本。

python脚本沿着文件的长度切割音频文件(如果需要的话批量处理),直到到达文件末尾。默认情况下,它会将文件分割成2秒的块,每个块从下一个块的末尾开始,每个块输出为一个单独的文件(输入到包含输入文件的文件夹中;文件输出名称按照输入,但与将原始文件中的位置添加到输出文件名称中)。输出切片的默认格式是16位,48kHz,单声道。用户可以将样本压碎为8位宽度,或者将其设置为中等(16位)或高质量(32位)。采样率可以从低质量(11025Hz)到高质量(48000Hz)的任何地方 - 实际上,采样率可以是任何你想要的,但是你的计算机可能不知道如何处理那些非标准的速率(例如,我测试过它与1赫兹和iTunes试图播放时死了 - 请参阅标准/接受选项的帮助菜单[python SliceAudio.py -h])。用户还可以改变样本切片长度和前一个切片上的重叠切片(例如,您可以切片成10秒的切片,每个后续切片沿1秒切片,与前一个切片重叠1秒钟。毫秒,所以将x-乘以1000,以秒为单位获得所需的切片长度)。有一个立体声输出选项。该脚本可以输入和输出ffmpeg **支持的任何格式。

依赖关系: 1. GCC 2. pydub(sudo pip install pydub),见github.com/jiaaro/pydub 3. ffmpeg的(brew install libav --with-libvorbis --with-sdl --with-theora) 4. audioread(sudo pip install audioread

实例:蟒SliceAudio。 PY -i xyz.m4a -f M4A -B 2 -S 11025 -l 10000蟒蛇SliceAudio.py -h

**的ffmpeg格式:trac.ffmpeg.org/wiki/audio%20types

相关问题