Support for various audio-loading backends instead of always relying on SoundFile
COLLABORATOR
Hi! 

You can use `set_transform`/`with_transform` to define a custom decoding for audio formats not supported by `soundfile`:
```python
audio_dataset_amr = Dataset.from_dict({"audio": ["audio_samples/audio.amr"]})

def decode_audio(batch):
    batch["audio"] = [read_ffmpeg(audio_path) for audio_path in batch["audio"]]
    return batch

audio_dataset_amr.set_transform(decode_amr) 
```

Supporting multiple backends is more work to maintain, but we could consider this if we get more requests such as this one.
2023-05-05T13:52:36Z
https://github.com/huggingface/datasets/issues/5782#issuecomment-1536295232
https://api.github.com/repos/huggingface/datasets/issues/5782
IC_kwDODunzps5bkgFA
https://api.github.com/repos/huggingface/datasets/issues/comments/1536295232/reactions
2023-05-05T13:52:36Z
https://api.github.com/repos/huggingface/datasets/issues/comments/1536295232
https://avatars.githubusercontent.com/u/47462742?v=4
https://api.github.com/users/mariosasko/events{/privacy}
https://api.github.com/users/mariosasko/followers
https://api.github.com/users/mariosasko/following{/other_user}
https://api.github.com/users/mariosasko/gists{/gist_id}
https://github.com/mariosasko
mariosasko
MDQ6VXNlcjQ3NDYyNzQy
https://api.github.com/users/mariosasko/orgs
https://api.github.com/users/mariosasko/received_events
https://api.github.com/users/mariosasko/repos
https://api.github.com/users/mariosasko/starred{/owner}{/repo}
https://api.github.com/users/mariosasko/subscriptions
User
https://api.github.com/users/mariosasko
public
CONTRIBUTOR
Could it be put somewhere as an example tip or something?
2023-05-09T13:56:29Z
https://github.com/huggingface/datasets/issues/5782#issuecomment-1540176761
https://api.github.com/repos/huggingface/datasets/issues/5782
IC_kwDODunzps5bzTt5
https://api.github.com/repos/huggingface/datasets/issues/comments/1540176761/reactions
2023-05-09T13:57:02Z
https://api.github.com/repos/huggingface/datasets/issues/comments/1540176761
https://avatars.githubusercontent.com/u/10278877?v=4
https://api.github.com/users/mariusz-jachimowicz-83/events{/privacy}
https://api.github.com/users/mariusz-jachimowicz-83/followers
https://api.github.com/users/mariusz-jachimowicz-83/following{/other_user}
https://api.github.com/users/mariusz-jachimowicz-83/gists{/gist_id}
https://github.com/mariusz-jachimowicz-83
mariusz-jachimowicz-83
MDQ6VXNlcjEwMjc4ODc3
https://api.github.com/users/mariusz-jachimowicz-83/orgs
https://api.github.com/users/mariusz-jachimowicz-83/received_events
https://api.github.com/users/mariusz-jachimowicz-83/repos
https://api.github.com/users/mariusz-jachimowicz-83/starred{/owner}{/repo}
https://api.github.com/users/mariusz-jachimowicz-83/subscriptions
User
https://api.github.com/users/mariusz-jachimowicz-83
public
COLLABORATOR
Considering the number of times a custom decoding transform has been suggested as a solution, an example in the [docs](https://huggingface.co/docs/datasets/process#format-transform) would be nice.

cc @stevhliu 
2023-05-09T16:26:48Z
https://github.com/huggingface/datasets/issues/5782#issuecomment-1540496480
https://api.github.com/repos/huggingface/datasets/issues/5782
IC_kwDODunzps5b0hxg
https://api.github.com/repos/huggingface/datasets/issues/comments/1540496480/reactions
2023-05-09T16:26:48Z
https://api.github.com/repos/huggingface/datasets/issues/comments/1540496480
https://avatars.githubusercontent.com/u/47462742?v=4
https://api.github.com/users/mariosasko/events{/privacy}
https://api.github.com/users/mariosasko/followers
https://api.github.com/users/mariosasko/following{/other_user}
https://api.github.com/users/mariosasko/gists{/gist_id}
https://github.com/mariosasko
mariosasko
MDQ6VXNlcjQ3NDYyNzQy
https://api.github.com/users/mariosasko/orgs
https://api.github.com/users/mariosasko/received_events
https://api.github.com/users/mariosasko/repos
https://api.github.com/users/mariosasko/starred{/owner}{/repo}
https://api.github.com/users/mariosasko/subscriptions
User
https://api.github.com/users/mariosasko
public
### Feature request

Introduce an option to select from a variety of audio-loading backends rather than solely relying on the SoundFile library. For instance, if the ffmpeg library is installed, it can serve as a fallback loading option.

### Motivation

- The SoundFile library, used in [features/audio.py](https://github.com/huggingface/datasets/blob/649d5a3315f9e7666713b6affe318ee00c7163a0/src/datasets/features/audio.py#L185), supports only a [limited number of audio formats](https://pysoundfile.readthedocs.io/en/latest/index.html?highlight=supported#soundfile.available_formats). 
- However, current methods for creating audio datasets permit the inclusion of audio files in formats not supported by SoundFile. 
- As a result, developers may potentially create a dataset they cannot read back.

In my most recent project, I dealt with phone call recordings in `.amr` or `.gsm` formats and was genuinely surprised when I couldn't read the dataset I had just packaged a minute prior. Nonetheless, I can still accurately read these files using the librosa library, which employs the audioread library that internally leverages ffmpeg to read such files.

Example:
```python
audio_dataset_amr = Dataset.from_dict({"audio": ["audio_samples/audio.amr"]}).cast_column("audio", Audio())
audio_dataset_amr.save_to_disk("audio_dataset_amr")
audio_dataset_amr = Dataset.load_from_disk("audio_dataset_amr")
print(audio_dataset_amr[0])
```
Results in:
```
Traceback (most recent call last):
...
    raise LibsndfileError(err, prefix="Error opening {0!r}: ".format(self.name))
soundfile.LibsndfileError: Error opening <_io.BytesIO object at 0x7f316323e4d0>: Format not recognised.
```

While I acknowledge that support for these rare file types may not be a priority, I believe it's quite unfortunate that it's possible to create an unreadable dataset in this manner.

### Your contribution

I've created a [simple demo repository](https://github.com/BoringDonut/hf-datasets-ffmpeg-audio) that highlights the mentioned issue. It demonstrates how to create an .amr dataset that results in an error when attempting to read it just a few lines later.

Additionally, I've made a [fork with a rudimentary solution](https://github.com/BoringDonut/datasets/blob/fea73a8fbbc8876467c7e6422c9360546c6372d8/src/datasets/features/audio.py#L189) that utilizes ffmpeg to load files not supported by SoundFile.


Here you may see github actions fails to read `.amr` dataset using the version of the current dataset, but will work with the patched version:
- https://github.com/BoringDonut/hf-datasets-ffmpeg-audio/actions/runs/4773780420/jobs/8487063785
- https://github.com/BoringDonut/hf-datasets-ffmpeg-audio/actions/runs/4773780420/jobs/8487063829

As evident from the GitHub action above, this solution resolves the previously mentioned problem.

I'd be happy to create a proper pull request, provide runtime benchmarks and tests if you could offer some guidance on the following:
- Where should I incorporate the ffmpeg (or other backends) code? For example, should I create a new file or simply add a function within the Audio class?
- Is it feasible to pass the audio-loading function as an argument within the current architecture? This would be useful if I know in advance that I'll be reading files not supported by SoundFile.

A few more notes:
- In theory, it's possible to load audio using librosa/audioread since librosa is already expected to be installed. However, librosa [will soon discontinue audioread support](https://github.com/librosa/librosa/blob/aacb4c134002903ae56bbd4b4a330519a5abacc0/librosa/core/audio.py#L227). Moreover, using audioread on its own seems inconvenient because it requires a file [path as input](https://github.com/beetbox/audioread/blob/ff9535df934c48038af7be9617fdebb12078cc07/audioread/__init__.py#L108) and cannot work with bytes already loaded into memory or an open file descriptor (as mentioned in [librosa docs](https://librosa.org/doc/main/generated/librosa.load.html#librosa.load), only SoundFile backend supports an open file descriptor as an input).