【问题标题】:Resolving 'ValueError: Unexpected end of file.' from scipy/wavfile/read解决“ValueError:文件意外结束。”从 scipy/wavfile/读取
【发布时间】:2019-03-27 23:23:04
【问题描述】:

我正在使用 Java WavFile 类的迭代方法在 Java 中拆分立体声 wav 文件。当我使用 python 读取生成的单声道 wav 文件并使用 scipy.io.wavfile 中的读取方法输出采样率和数据时,出现错误:

'值错误:文件意外结束。'

我尝试的其他单声道 wav 文件没有出现此错误,只有我使用 Java 制作的文件。查看其他论坛帖子,我知道这一定与我如何设置文件的标题信息有关,但是,在尝试争吵并阅读 API 文档以确保我的用法正确之后,我不知所措。

我的 Java 代码

try {
            WavFile srcFile = WavFile.openWavFile(this.audioFile);

            long numFrames = srcFile.getNumFrames();
            long sampleRate = srcFile.getSampleRate(); 
            int channels = 2;
            int bitRate = 16;


            File[] files = new File[channels];
            WavFile[] wavFiles = new WavFile[channels];

            for (int i = 1; i < channels + 1; i++) {
                //Populates File Array
                files[i - 1] = new File("output" + i + ".WAV");
                wavFiles[i - 1] = WavFile.newWavFile(files[i - 1], 1, numFrames, bitRate, sampleRate);
            }

            int bufferLength = Math.toIntExact(numFrames);

            int[][] buffer = new int[channels][bufferLength];

            long frameCounter = 0;

            while (frameCounter < numFrames){
                srcFile.readFrames(buffer,bufferLength);

                for (int j = 0; j<channels;j++){
                    wavFiles[j].writeFrames(buffer[j],bufferLength);
                }

                frameCounter += bufferLength;
            }

        } catch (Exception ex) {
            System.out.println("WavFile failed to open source file: " + ex);
        }

从wav文件中提取数据的简单python代码

import scipy.io.wavfile as wav

fs, data = wav.read(file)

wav.close()

根据我的理解,python 代码在读取 wav 文件时应该没有问题,无论其来源如何。

【问题讨论】:

  • 您能否链接到您的 Java 代码生成的文件之一?
  • 我不完全确定这会起作用,但作为一个建议,尝试通过以下方式放置您的 wav 文件:ffmpeg -i "orig.wav" -f wav -bitexact -acodec pcm_s16le -ar 22050 -ac 1 "ffmpeg.wav",然后尝试再次运行 python 脚本。另外,尝试使用 ffmpeg 创建一个 wav 文件以查看它是否运行。这只是为了排除安装错误的可能性。
  • 这是一个保管箱链接。我希望这行得通。 dropbox.com/s/leolwqmimiriqab/output1.WAV?dl=0
  • 使用 ffmpeg 允许代码运行。它究竟是做什么的?明天我有空的时候再读一读。但是,如果您愿意用自己的话来表达,那会有所帮助。
  • 我只需要关闭语句。 ffmpeg 确保存在标头信息所述的帧数量。

标签: java python scipy wav


【解决方案1】:

您的 Java 代码永远不会为 wavFiles[j] 调用 close() 方法。根据http://www.labbookpages.co.uk/audio/javaWavFiles.htmlclose() 方法“必须在使用 writeFrames 方法写入所有样本后调用。如果不调用,wav 文件可能不完整。”

【讨论】:

  • 这绝对是问题所在。 python 程序现在可以运行 wav 文件,而无需使用任何第三方软件。感谢您的输入和链接。
【解决方案2】:

您在head of wav file 中的数据似乎不正确。我很确定文件中的帧数小于实际帧数。

您可以尝试在Java代码中查找错误根源,也可以使用对头错误更具弹性的Python库,例如内置库wave

>>> import wave
>>> track = wave.open('output1.WAV', 'r')
>>> track.getnframes()
3417927
>>> track.readframes(10)
b'\x00\x00\x00\x00\xff\xff\x01\x00\x01\x00\xfe\xff\x01\x00\x00\x00\xff\xff\x01\x00'

不要忘记使用track.close() 或使用with statement 以避免内存泄漏。

【讨论】:

  • 我会尝试使用更通用的 wav 文件阅读器。但是,3417927 也是原始帧数。至少根据java wav文件类有的方法。
  • @AndrewA。对,因为wave 计算来自流的帧数,而不是来自标头的帧数。我在向您提供的文件添加 3726 字节的零填充时检查了 wavfile 是否有效,但我不知道 Java 代码中的错误在哪里。
  • 这是我缺乏密切的陈述。我使用的其他类不需要它们,所以我忘了在这个方法中添加它们。这创建了一个与标题数据不匹配的未完成的 .wav 文件。谢谢,您的信息帮助我确认了关闭问题。
猜你喜欢
  • 2018-02-05
  • 2017-08-02
  • 1970-01-01
  • 1970-01-01
  • 2015-08-20
  • 1970-01-01
  • 2012-06-10
相关资源
最近更新 更多