import matplotlib.pyplot as plt
from scipy import signal
from scipy.io import wavfile
def get_audio_code(file):
sample_rate, samples = wavfile.read(file)
frequencies, times, spectrogram = signal.spectrogram(samples, sample_rate)
print(f'{frequencies=}', len(frequencies))
print(f'{times=}', len(times))
print(f'{spectrogram=}', type(spectrogram))
# [[print(f'{type(i)} {i}') for i in row] for row in spectrogram[:1]]
# plt.pcolormesh(times, frequencies, spectrogram)
# plt.imshow(spectrogram)
# plt.ylabel('Frequency [Hz]')
# plt.xlabel('Time [sec]')
# plt.show()
return times, frequencies, spectrogram
ffmpeg -i test2.mp4 -acodec pcm_u8 -ac 1 -ar 22050 test2.wav
然后获取频谱,其中spectrogram.T行列转换之后就是一个包含[时间:[编码,...],...]的数组。
然后对数组做简单的近似匹配,广告在开头的时候捕获成功,广告在结尾捕获失败。
感觉问题还是广告的开始点,和几次转码的时间点,匹配上有问题。
用数组直接做近似匹配不行,可能需要提取其它特征,比如增幅变化或者别的。
但感觉为了这么个东西也犯不上费太大功夫,先告一段落。
参考:worldveil/dejavu: Audio fingerprinting and recognition in Python
1
imn1 2020-01-16 20:40:17 +08:00
两年前搜过,需求和你差不多——自动提取音量提别大一段
没有什么好的结果,两年后今天不知如何 |
2
JCZ2MkKb5S8ZX9pq OP @imn1 我倒也不是要音量大,音量大的话,Adobe Premiere 或者 audition 都能搞到平均音量,可以批处理。
我主要是嫌贴片烦,同样的内容听几十次实在是太折磨了,要么就要每次都手动跳过。 截取视频之前搞过,ffmpeg 很简单。但音频没弄过,稍微搜了一下也没看到特别符合的。 我考虑是采集频谱特征,比如分 16 阶转成 16 进制,然后把开头 10 秒和最后 20%做一下比对,有符合的就掐头去尾。 但音频又涉及时间,简单比较可能会有误差,所以想看看有没有什么现成的算法。 |
3
also24 2020-01-16 20:53:43 +08:00
|
4
1462326016 2020-01-16 20:55:31 +08:00
如果是同样的广告的话尝试下 ffmpeg 将一段时间内的视频分割成图片,然后对比图片,是不是能好一点?仅仅是提供个思路,未实验
|
5
JCZ2MkKb5S8ZX9pq OP @1462326016 思路可以,但不完全行。
因为部分油管下载我都是按最低质量下的,下载到的文件音视频分离,而我基本只听不看,就只保留了音频。。。。。。 |
6
JCZ2MkKb5S8ZX9pq OP @also24 这个也没解决吧
我现在在看另一个做声音指纹的库 提取声音,对某一个时刻编码比较,这都不难。 我现在有问题的点是时间。 比如 0.5 秒一采集,但广告出现的时间是不对齐的,所以很可能比对失误。 @1462326016 这个情况在比对纯图片的时候,也有可能出现。 如果是片头,而且剪的编辑负责,每次都对得很齐,那还好处理。片尾贴片的话很可能对不齐啊。 |
7
JCZ2MkKb5S8ZX9pq OP @1462326016 粗暴点的解决方案,是把切片密度做得足够细,假设每秒 30 帧每帧都切,反正都是在本地跑,牺牲点内存换精确。
|
8
qwjhb 2020-01-16 23:08:58 +08:00
语音转文字确认时间点可行吗
|
9
JCZ2MkKb5S8ZX9pq OP |
10
billlee 2020-01-16 23:21:35 +08:00
应该可以用匹配滤波器
|
11
JCZ2MkKb5S8ZX9pq OP 感觉这个东西有点类似在一个画面上,找出目标图形,那个倒还算简单,有很多现成方案。
但因为音频文件涉及时间,同时我对音频文件格式也完全不熟悉,没有什么思路,也搞不清它内部怎么转换的。 还是需要这个领域的专家来提提建议。 我觉得可以把题目转换为 ========================== 如何在一段音频中,锁定目标音频的起点。 ========================== 类似于 string.indexOf 的一个方法 |
12
JCZ2MkKb5S8ZX9pq OP @billlee 看 append,我试了一下,但是失败了。
不熟悉音频格式,排查起来有点艰难。 |
13
JCZ2MkKb5S8ZX9pq OP @billlee 其实中途的思路,就是把频谱打出来,然后以图找图,在源视频里找到广告的部分。
但因为直接拿到数组就用数组配了,然后没成。 不知道都转成图,然后用图找图的方式会不会好点。 但这个同样一段贴片广告,涉及到后期人员的操作,音量音调变速压缩率,以及视频平台各个时期的压缩设置,和种种不确定因素。感觉不会那么顺利。 |
14
billlee 2020-01-17 00:02:17 +08:00
@JCZ2MkKb5S8ZX9pq #13 这样转频谱损失的信息太多了吧,如果音频只是经过剪辑,没有变调变速,在时域上直接用匹配滤波器应该是效果很好的。
dsp.stackexchange.com/questions/24548/detecting-a-specific-pop-in-a-real-time-audio-signal |
15
JCZ2MkKb5S8ZX9pq OP @billlee 问题不转码,我不知道怎么把声音放到统一的时域下,这就回到了那个声音文件的记录方式的问题上了,我不知道怎么去匹配那个时间。
|
16
breaker911 2020-01-17 00:09:43 +08:00 via Android
不如使用开源播放器 然后加入类似于网络剧一样的跳过片头功能 特征大概就找找音量大小和中间间隔或者特征帧匹配?
|
17
TimePPT 2020-01-17 00:35:10 +08:00 via Android
你需要的是分时的音频指纹
|
18
lishunan246 2020-01-17 01:47:08 +08:00 via Android
可以试试把两段音频当作一维信号处理,在傅立叶频域上计算互相关。
根据互相关最大值判断是否存在广告,根据最大值位置判断时间点。 |
19
dizun 2020-01-17 12:20:50 +08:00
没做过类似的,有个不成熟的思路 。
假设视频架构 ( 广告-》正片)。 广告和正片之间应该有一个通用且明显的部分,例如正片的标题。 将视频转换成二进制,直接模糊搜索正片的标题,截取标题到结尾。 不知道可行吗? |
20
JCZ2MkKb5S8ZX9pq OP @dizun 由于 MP4/AAC 压缩问题,估计不可行。
|
21
no1xsyzy 2020-01-17 12:54:36 +08:00
首先,因为有编码肯定是在频域内处理才行
听觉心理学?测算心理音量设阈值作启发 频谱算 corelation ? |
22
JCZ2MkKb5S8ZX9pq OP @no1xsyzy 不是音量的问题 是内容匹配
|
23
JCZ2MkKb5S8ZX9pq OP @JCZ2MkKb5S8ZX9pq 比如片头会有一段烦人音效,或者片尾推荐几分钟公众号。
|
24
no1xsyzy 2020-01-17 13:25:01 +08:00
@JCZ2MkKb5S8ZX9pq
> 无奈片头片尾贴片广告太多了,音量都暴大 “音量” 是作为特征而非目标 做成音量启发式,那样的话可以只搜十秒不到,那每秒 30 采样问题也不大。 如果这样效果不好,就是频域内选个四五条线做 corelation,你甚至不需要专门采样比对 |
25
JCZ2MkKb5S8ZX9pq OP @no1xsyzy 可是音量无法作为特征,因为几百段里,也有贴片的音量正常的,或者节目中途又加了其它音效的。情况比较复杂,音量大只是出现在一部分片头上。
|
26
cshlxm 2020-01-17 14:18:15 +08:00
一段音频用 vad 检测算法,分离出音频段,调用语音转文字接口,转一部分文字出来,分词,做文本相关性分析,把相关系数高的文字对应音频找出来即可
|
27
Ukenn 2022-08-09 14:17:35 +08:00
@JCZ2MkKb5S8ZX9pq 你好,请问能分享一下你写的么,看了许多完全没有头绪想参考一下,匹配到开始对我来说足够了,由于我项目广告的时间是固定的,我想加上广告时长应该就可以匹配到结尾了
|