Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ignore invalid wav size for files larger than 4GiB #101

Open
milahu opened this issue Jun 18, 2024 · 0 comments
Open

ignore invalid wav size for files larger than 4GiB #101

milahu opened this issue Jun 18, 2024 · 0 comments

Comments

@milahu
Copy link

milahu commented Jun 18, 2024

currently rubberband honors invalid wav sizes
and silently produces cropped output files

$ ffmpeg -i src.mkv -map 0:a:0 src.mkv.a0.wav
[wav @ 0x586900] Filesize 5088049254 invalid for wav, output file will be broken
[out#0/wav @ 0x5858c0] video:0kB audio:4968798kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000002%
size= 4968798kB time=02:27:13.40 bitrate=4608.0kbits/s speed=5.81x    

$ # fix tempo from 24 to 24000/1001 fps

$ rubberband --time 1.001 src.mkv.a0.wav src.mkv.a0.wav.fixed-tempo.wav

$ ffprobe-get-duration.sh *mkv *wav
8833.418000  02:27:13.418000  src.mkv
8833.418667  02:27:13.418667  src.mkv.a0.wav
7463.996979  02:04:23.996979  src.mkv.a0.wav.fixed-tempo.wav

$ du -b *wav
5088049254      src.mkv.a0.wav
4299262340      src.mkv.a0.wav.fixed-tempo.wav

$ python -c 'print(4299262340/1024/1024/1024)'
4.004000071436167

$ ffmpeg -i src.mkv.a0.wav 2>&1 | grep Audio
  Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 48000 Hz, 5.1(side), s16, 4608 kb/s

$ mpv src.mkv --audio-file=src.mkv.a0.wav
[ffmpeg/demuxer] wav: Ignoring maximum wav data size, file may be invalid
[ffmpeg/demuxer] wav: Estimating duration from bitrate, this may be inaccurate

https://en.wikipedia.org/wiki/WAV

The WAV format is limited to files that are less than 4 GiB, because of its use of a 32-bit unsigned integer to record the file size in the header. Although this is equivalent to about 6.8 hours of CD-quality audio at 44.1 kHz, 16-bit stereo, it is sometimes necessary to exceed this limit, especially when greater sampling rates, bit resolutions or channel count are required. The W64 format was therefore created for use in Sound Forge. Its 64-bit file size field in the header allows for much longer recording times. The RF64 format specified by the European Broadcasting Union has also been created to solve this problem.

ffprobe-get-duration.sh
#!/bin/sh
# https://trac.ffmpeg.org/wiki/FFprobeTips#Formatcontainerduration
set -e
set -u
for f in "$@"; do
  # duration in float seconds, including milliseconds
  duration=$(ffprobe -i "$f" -loglevel 0 -show_entries format=duration -of default=nw=1:nk=1)
  # get nanoseconds. jq does not support %f or %N format
  duration_ns=${duration#*.}
  if [ "$duration" = "$duration_ns" ]; then
    duration_ns=000000
  fi
  duration_h=$(echo $duration | jq -r 'tonumber | strftime("%H:%M:%S")').$duration_ns
  echo "$duration  $duration_h  $f"
done

possible workarounds

  • split by time
  • split channels
  • downmix surround sound to stereo
  • use a different format than wav
    • caf - not supported by rubberband
    • flac - not supported by rubberband
    • RF64 - ffmpeg -i src.mkv -rf64 auto src.wav

RF64 works

$ ffmpeg -i src.mkv -map 0:a:0 -rf64 auto src.mkv.a0.rf64.wav
$ rubberband --time 1.001 src.mkv.a0.rf64.wav src.mkv.a0.rf64.wav.fixed-tempo.wav
$ ffprobe-get-duration.sh *wav
8833.418667  02:27:13.418667  src.mkv.a0.rf64.wav
8842.252083  02:27:22.252083  src.mkv.a0.rf64.wav.fixed-tempo.wav
$ python -c 'print(8833.418667 * 1.001)'
8842.252085667
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant