Search Issue Tracker

By Design

Votes

1

Found in

2022.3.52f1

6000.0.28f1

6000.1.0a5

6000.2.0a1

6000.3.0a1

Issue ID

UUM-87265

Regression

No

.mp3 playback position is inaccurate when loaded with .streamAudio while in Play Mode

-

Reproduction steps:
1. Open the attached “UUM-87265“ project
2. Open the “Assets/Scenes/SampleScene.unity“ Scene
3. Enter the Play Mode
4. Press the “Start Audio OK“ button and listen to the audio
5. Press the “Stop Audio“ button
6. Press the “Start Audio Broken“ button and listen to the audio

Expected result: Audio started by both buttons sounds identical as the playback position is the same
Actual result: Audio started by the “Start Audio Broken“ button has a different starting position

Reproducible with: 2021.3.46f1, 2022.3.52f1, 6000.0.28f1, 6000.1.0a5

Reproducible on: Windows 10 (22H2), MacOS 15.1
Not reproducible on: No other environments tested

Note: Reproducible in Player

  1. Resolution Note:

    The audio seeking was bad because the provided mp3 test file had no seek table embedded.

    # Explanation

    ## 1. MP3 seeking

    MP3 files are notoriously bad at seeking and looping. The reason for this is rooted in the notion that audio samples are grouped in frames (think "packet") and while these frames are identical in binary size they contain a different count of samples, due to variable bit rates and compression techniques. Consequently, with simple MP3 files you cannot seek precisely to a specific sample or time. You can only estimate a position based on the size of the file and seek to the beginning of the closest frame, which will frequently lead around the desired position, likely with a gap in the order of a few seconds.

    To improve on that, a seek table (historically called Xing table) can be embedded in MP3 files, and acts as a table of content allowing to target much more accurately the desired position.

    Unity happens to support this, and if we add a seek table to the file provided in the bug repro, it seeks as precisely as the OGG file does. This can easily be done with FFMPEG.

    ## 2. Issue only happening when streaming audio

    In the bug repro, the audio files are loaded via WebRequest. They are downloaded from a remote or local source, decoded on the fly and made available as an AudioClip. The download handler has an option allowing the streaming of the audio (for faster playback start and lower memory footprint, at the cost of more CPU).

    In the scenario where the audio file it fetched without streaming, the binary file is completely downloaded, fully read and decompressed with the MP3 codec. Then when seeking happens, all the audio samples are already decoded and available, so the audio file can be seeked as a PCM array with a basic DSP, with an almost-sample-perfect precision.

    In the scenario where the audio file it fetched with streaming enabled, the binary file is downloaded a few kB at the time, partially read and decoded by the MP3 codec. When the seeking operation happens, if no seek table was available in the file header when the streaming started, it will have no choice to approximate the seeking position based on the file size, download that file chunk and start reading from there. If a seek table is available, then it will detect it when starting the file streaming and be able to know what binary offset to look for to make the better choice of chunk to download.

Add comment

Log in to post comment

All about bugs

View bugs we have successfully reproduced, and vote for the bugs you want to see fixed most urgently.