将音频文件拆分为任意大小的片段

时间:2013-12-20 05:08:04

标签: r file-io split audio

我有一个很大的声音文件(150 MB),我想把它分成一些更容易管理的小文件,比如说有5分钟音频的文件。显然,最后一段将是<= 5分钟,那没关系。有没有办法轻松完成这类任务?

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

这是我到目前为止所尝试的内容。我使用readMP3中的tuneR导入数据,并将使用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

3 个答案:

答案 0 :(得分:3)

在@Jean V. Adams的优秀答案的基础上,我找到了一个使用索引的解决方案(即[)。

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根据我的意思将输出对象更改为单声道。

答案 1 :(得分:2)

我没有使用R中的音频文件的经验,但我能够提出一种可能对您有帮助的方法。看看下面的代码。

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

答案 2 :(得分:0)

检查https://github.com/schultzm/SliceAudio.py 我写了这个脚本来做一个与这个问题中提到的非常相似的东西,但是我在python中写了它。不确定它是否仍然相关,但无论如何这里是我的解决方案。如果需要,您可以从R中启动python脚本。

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

支持的任何格式

依赖关系: 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

示例用法:python SliceAudio.py -i xyz.m4a -f m4a -b 2 -s 11025 -l 10000 python SliceAudio.py -h

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