Ffmpeg-python: Convert video to wav audio get a wrong file header

Created on 27 Aug 2018  路  2Comments  路  Source: kkroening/ffmpeg-python

I use this code to convert video file to wav audio:
out, err = (ffmpeg
.input('test.mp4')
.output('-', format='wav', bits_per_raw_sample=16, ac=1, ar=16000)
.overwrite_output()
.run(capture_stdout=True, capture_stderr=True)
)
then I found a wrong wav format header in out and cannot read by wavfile
from scipy.io import wavfile
f = io.BytesIO()
f.write(out)
f.seek(0)
sr, wav_data = wavfile.read(wav_file)
when I run this code I got this error
File "/Users/edisonwu/PycharmProjects/eas_pyalphavideo/wav_proc.py", line 99, in wavfile_to_examples
sr, wav_data = wavfile.read(wav_file)
File "/Users/edisonwu/PycharmProjects/eas_pyalphavideo/ENV/lib/python2.7/site-packages/scipy/io/wavfile.py", line 246, in read
raise ValueError("Unexpected end of file.")
ValueError: Unexpected end of file.

so I dump out to a file, I found the ChunkSize in the RIFF header was 'ffff ffff' , and the subchunksize in the data header was 'ffff ffff' too.
image

but I use command ffmpeg -i test.mp4 -ar 16000 -ac 1 -bits_per_raw_sample 16 -y test.wav I got a right wav file.
image

Most helpful comment

Just like @kkroening said, this problem is yielded by FFmpeg itself rather than this Python wrapper. You could fix this problem by modifying the ChunkSize manually. For instance,

import ffmpeg
from scipy.io import wavfile

stdout, err = (
    ffmpeg
    .input('test.mp4')
    .output('-', format='wav', bits_per_raw_sample=16, ac=1, ar=16000)
    .overwrite_output()
    .run(capture_stdout=True, capture_stderr=True)
)

riff_chunk_size = len(stdout) - 8
quotient = riff_chunk_size

binarray = list()
for _ in range(4):
    quotient, remainder = divmod(quotient, 256)  # every 8 bits
    binarray.append(remainder)

riff = stdout[:4] + bytes(binarray) + stdout[8:]
rate, signal = wavfile.read(io.BytesIO(riff))

You could find more details in here.

All 2 comments

ffmpeg does weird things when writing to pipes. Sometimes it takes extra arguments to tell it to not be dumb. I'm not sure exactly what args you'd need in this scenario. I suspect though that if you change your command above from ... -y test.wav to ... -y - > test.wav you'll see the same issue whether running directly against ffmpeg or through ffmpeg-python.

Just like @kkroening said, this problem is yielded by FFmpeg itself rather than this Python wrapper. You could fix this problem by modifying the ChunkSize manually. For instance,

import ffmpeg
from scipy.io import wavfile

stdout, err = (
    ffmpeg
    .input('test.mp4')
    .output('-', format='wav', bits_per_raw_sample=16, ac=1, ar=16000)
    .overwrite_output()
    .run(capture_stdout=True, capture_stderr=True)
)

riff_chunk_size = len(stdout) - 8
quotient = riff_chunk_size

binarray = list()
for _ in range(4):
    quotient, remainder = divmod(quotient, 256)  # every 8 bits
    binarray.append(remainder)

riff = stdout[:4] + bytes(binarray) + stdout[8:]
rate, signal = wavfile.read(io.BytesIO(riff))

You could find more details in here.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Baa14453 picture Baa14453  路  5Comments

ghost picture ghost  路  3Comments

Woolwit picture Woolwit  路  4Comments

CNugteren picture CNugteren  路  5Comments

Matttman picture Matttman  路  6Comments