Bad audio format for WAV

博客作者在尝试使用Keras进行音频分类时遇到问题,错误提示为'BadaudioformatforWAV'。通过检查发现音频格式不匹配,期望为1,但实际为3。解决方案包括使用librosa进行音频提取,检查路径是否正确,使用mediaArea软件查看音频信息,并最终通过ffmpeg转换音频格式。此外,作者还分享了关于tensorflow.io的了解,C盘清理技巧,快速的豆瓣pip源,以及如何使用echo批量执行CMD命令来转换多个音频文件。
部署运行你感兴趣的模型镜像

1. 问题描述

运行keras音频分类教程的时候,用自带16000_pcm_speeches的数据集可以在pycharm里面跑通,换成自己的音频就不可以了,报错
Bad audio format for WAV: Expected 1 (PCM), but got3

2. 解决

2.1使用librosa进行提取

使用tensorflow的decode和encode,期待能配准格式
音频格式问题在代码里有两个部分,

def path_to_audio(path):
    """Reads and decodes an audio file."""
    print('path_to_audio, path : ',path)

    # yyy = wl.decode_wav(path) # mine
    # audio, _ = tf.audio.decode_wav(yyy, 1, SAMPLING_RATE)


    # yyy = wl.decode_wav2(path)
    # SAMPLING_RATE = 16000
    # audio, _ = tf.audio.decode_wav(yyy, 1, SAMPLING_RATE)
    SAMPLING_RATE = 16000

    # TODO : origin
    # audio = tf.io.read_file(path)
    # audio, _ = tf.audio.decode_wav(audio, 1, SAMPLING_RATE)

    # TODO : mine
    yyy = wl.decode_wav2(path)
    audio, _ = tf.audio.decode_wav(yyy, 1, SAMPLING_RATE)

    return audio
def load_noise_sample(path):
    # yyy = wl.decode_wav(path)
    # sample, sampling_rate = tf.audio.decode_wav(yyy, desired_channels=1)

    sample, sampling_rate = tf.audio.decode_wav(
        tf.io.read_file(path), desired_channels=1
    )

    if sampling_rate == SAMPLING_RATE:
        # Number of slices of 16000 each that can be generated from the noise sample
        slices = int(sample.shape[0] / SAMPLING_RATE)
        sample = tf.split(sample[: slices * SAMPLING_RATE], slices)
        return sample
    else:
        print("Sampling rate for {} is incorrect. Ignoring it".format(path))
        return None

问题出在 tf.audio.decode_wav和 tf.io.read_file(path)
尝试使用别的方法加载音频,放到decode里面

def wl_decode_wav(fname):
    y, s = librosa.load(fname,sr=16000) # Downsample 44.1kHz to 8kHz   
    yy = tf.expand_dims(y, axis=1)
    yyy = tf.audio.encode_wav(yy, sample_rate=16000, name=None)
#     print(yyy)
    
    return yyy
yyy = wl_decode_wav(fname)
sample, sampling_rate = tf.audio.decode_wav(yyy, desired_channels=1)
print(tf.audio.decode_wav(yyy, desired_channels=1))

用这种方式可以获得相同的数据和相同的对象格式,DecodeWav(audio=<tf.Tensor: shape=(16000, 1), dtype=float32和tf.Tensor: shape=(16000, 1), dtype=float32,但是放到代码里面还是报错。

2.2 路径错误

有时斜杠和反斜杠也会导致错误,使用split和join进行处理,依然报错

def change_path(path):
    # path = 'D:\\datas\\16000_pcm_speeches\\audio\\Nelson_Mandela\\999.wav'
    p = path.split('\\')
    pp = '/'.join(p)
    return pp
    

2.3 mediaArea查看音频信息

打算不动里面的代码,从外部音频入手,调整音频格式
首先使用这个软件查看音频的不同
我的音频格式:

原始可以跑通的音频格式
在这里插入图片描述
应该是这里,和报错符合,希望得到1,但是得到了3

2.4 安装ffmpeg,转换音频格式

下载没有gui的软件ffmpeg,这个之前也有搜到过,但是用命令行显得很复杂,所以没有选。不过试错一波之后,还是要安装。根据这个博主的教程,轻松安装成功。
https://blog.youkuaiyun.com/xiaoxueyaoxuexi/article/details/110451006
转成功了再来
妙啊!
成功了
上面的三个错误是连着的
改了一个命令之后三个问题都解决了

ffmpeg -i input.wav -ab 256k output.wav

在cmd里输入这个命令就可以得到和模型原音频一样的格式
在这里插入图片描述
虽然有一点点奇怪的是257k
不过能跑就不管啦
感谢雷神

3. 顺便学到

3.1 tensorflow.io

这个用的人很少,找不到教程

3.2 c 盘清理

早就把桌面和下载,微信qq等的路径都移动到d盘了,但是可爱cc还是只剩200m+
不过没有困难的工作,只有勇敢的狗狗
狗狗这次在设置的储存管理里面,找到大的文件夹,然后再右键查看文件夹的属性,看到内存,把大内存的剪切粘贴到d盘,再扔一个快捷方式回来骗一骗cc,成功给cc扩容几个g🎈

3.3 比火箭还快的豆瓣pip源

在下载tensorflow.io的时候找到的,真的巨快!
在这里插入图片描述
有味道又很真实的评论,豆瓣源真的很快
这里是链接豆瓣源
https://blog.youkuaiyun.com/weixin_38109583/article/details/93376954

3.4 使用echo批量执行cmd命令

一个一个改是不可能的,python有和ffmpeg的包,但是感觉用法不同
用python的os.system模块也不太行,python安装在conda的一个环境下,儿ffmpeg本身只能在base环境查看到。
所以用了echo,写bat脚本

@echo off
echo +++++
echo hi
ffmpeg -version
d:
cd mydocument
cd temp
ffmpeg -i r1.wav -ab 256 k1.wav
pause

酱就可以了ヾ(≧▽≦*)o
接下来的任务是用python生成命令,然后复制过来

import os

audio_path='D:\\mydocument\\temp'

path_list = []
name_list = []
echo_list = []
for root, dirs, files in os.walk(audio_path, topdown=False):
    for name in files:
        path_list.append(os.path.join(root, name))
        name_list.append(name)
    for name in dirs:
        print(os.path.join(root, name))
print(path_list)
print(name_list)
for name in name_list:
    name_new = name + '_new.wav'
    echo = 'ffmpeg -i ' + name + ' -ab 256k ' + name_new
    echo_list.append(echo)
print(echo_list)

# Open the file for writing
F = open('list.txt', 'w')
for i in echo_list:
    F.write(str(i) + "\n")
F.close()

成功啦~

@echo off
echo +++++
echo hi
ffmpeg -version
d:
cd mydocument
cd temp
ffmpeg -i k1.wav -ab 256k k1.wav_new.wav
ffmpeg -i p1.wav -ab 256k p1.wav_new.wav
ffmpeg -i p2.wav -ab 256k p2.wav_new.wav
ffmpeg -i p3.wav -ab 256k p3.wav_new.wav
ffmpeg -i p4.wav -ab 256k p4.wav_new.wav
ffmpeg -i p5.wav -ab 256k p5.wav_new.wav
ffmpeg -i r1.wav -ab 256k r1.wav_new.wav
ffmpeg -i r2.wav -ab 256k r2.wav_new.wav
ffmpeg -i r3.wav -ab 256k r3.wav_new.wav
ffmpeg -i r4.wav -ab 256k r4.wav_new.wav
ffmpeg -i r5.wav -ab 256k r5.wav_new.wav

pause

复制过来,保存,双击运行,piu~的一下就完成了

您可能感兴趣的与本文相关的镜像

TensorFlow-v2.15

TensorFlow-v2.15

TensorFlow

TensorFlow 是由Google Brain 团队开发的开源机器学习框架,广泛应用于深度学习研究和生产环境。 它提供了一个灵活的平台,用于构建和训练各种机器学习模型

在Java中,`AudioInputStream` 是处理音频数据的核心类之一,通常用于读取、操作和播放音频文件。通过 `javax.sound.sampled` 包中的相关类,可以实现对音频流的获取、格式查询、截取、播放等操作。 ### 获取音频输入流并查询基本信息 可以通过 `AudioSystem.getAudioInputStream(File file)` 方法从本地音频文件中获取 `AudioInputStream` 实例,并从中提取音频格式和帧长度等信息: ```java import javax.sound.sampled.*; public class AudioInfo { public static void main(String[] args) { String fileName = "D:/all/demo/day/src/rxxj/BadApple.wav"; AudioInputStream audioInputStream = null; try { File file = new File(fileName); audioInputStream = AudioSystem.getAudioInputStream(file); AudioFormat format = audioInputStream.getFormat(); long frameLength = audioInputStream.getFrameLength(); System.out.println("音频格式: " + format); System.out.println("音频帧长度: " + frameLength); } catch (Exception e) { e.printStackTrace(); } finally { if (audioInputStream != null) { try { audioInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } } ``` 此代码展示了如何打开音频文件并打印其格式和帧长度[^1]。 ### 截取音频片段 若需要从音频文件中提取特定时间段的内容,可以使用 `AudioInputStream` 读取指定范围的数据并写入新文件。以下是一个截取音频的示例: ```java import javax.sound.sampled.*; import java.io.*; public class AudioTrimmer { public static void trimAudio(String sourceFile, String destinationFile, int startSecond, int duration) throws Exception { File source = new File(sourceFile); AudioInputStream inputStream = AudioSystem.getAudioInputStream(source); AudioFormat format = inputStream.getFormat(); long framesPerSecond = format.getFrameRate(); long startFrame = startSecond * framesPerSecond; long cutFrames = duration * framesPerSecond; inputStream.skip(startFrame * format.getFrameSize()); AudioInputStream subStream = new AudioInputStream(inputStream, format, cutFrames); AudioSystem.write(subStream, AudioFileFormat.Type.WAVE, new File(destinationFile)); subStream.close(); inputStream.close(); } public static void main(String[] args) { try { trimAudio("input.wav", "output.wav", 10, 30); // 从第10秒开始截取30秒 } catch (Exception e) { e.printStackTrace(); } } } ``` 该方法利用了 `skip()` 函数跳过起始部分,并通过构造新的 `AudioInputStream` 来限定输出的帧数,从而完成音频剪辑[^3]。 ### 播放音频流 要播放音频流,可使用 `Clip` 或 `SourceDataLine` 类来加载并播放音频数据。以下是一个基于 `Clip` 的简单播放器实现: ```java import javax.sound.sampled.*; import java.io.File; public class AudioPlayer { public static void playAudio(String filePath) { try { File file = new File(filePath); AudioInputStream audioStream = AudioSystem.getAudioInputStream(file); Clip clip = AudioSystem.getClip(); clip.open(audioStream); clip.start(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { playAudio("sound.wav"); } } ``` 此代码演示了如何打开音频文件并播放,适用于简单的音频播放场景[^4]。 ### 常见问题与解决方案 - **`IllegalStateException`:** 如果出现类似 `Clip is already open...` 的异常,请确保每次调用前都关闭了之前的 `Clip` 实例,或在播放前检查是否已打开。 - **音频格式不支持:** 若音频文件格式不受支持,可能抛出 `UnsupportedAudioFileException`。建议优先使用标准格式(如 WAV)进行测试。 - **路径问题:** 确保音频文件路径正确且具有读取权限,否则会引发 `FileNotFoundException` 或 `IOException`。 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值