IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Voir le flux RSS

r0d

Journal d'un développeur ivre : L'enfer de l'audio dans Unity #1

Noter ce billet
par
r0d
, 24/11/2020 à 22h00 (613 Affichages)
Unity est un très bon outil.

Par exemple, imaginons que vous souhaitez manipuler des textures, ou des images, ce qui revient au même, mais comme disait le grand-frère, "La guerre c'est la paix". Enfin bref. Si vous souhaitez importer, exporter, serialiser, manipuler des images dans Unity, vous avez à disposition pléthore de classes, fonctions, outils, tout ce dont vous avez besoin, parfois même tellement qu'on peut s'y perdre.
En revanche, si vous souhaitez manipuler des fichiers audio, j'aime autant vous prévenir de suite : c'est la chienlit !
Il n'y a même pas une fonction pour charger un fichier audio !
Non mais mais allô ?! Les mecs ils font un éditeur de jeu vidéo et ils prennent pas leur shampooing ?!

Nous, on aimerait bien pouvoir écrire du code genre :
Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
AudioSource source = AudioSource.LoadFromFile("C:/mon/son/qui/tue.wav");
Car c'est l'équivalent de ce que je fais pour mes textures.

Et bien non, on peut pas faire ça.
Tenez-vous bien, pour charger un fichier audio qui est sur votre disque dur, il faut utiliser... tenez-vous bien... un client http qui va faire une requête !
Voici un exemple de code fournit par les gars de la team Unity et qui est censé fonctionner :
Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
string url = "file://C:/mon/son/qui/tue.wav";
WWW audioLoader = new WWW(url);
while (!audioLoader.isDone)
   System.Threading.Thread.Sleep(100);
audioSource.clip = audioLoader.GetAudioClip(false, false, AudioType.WAV);
Bon c'est un peu relou, mais soit, allons-y.

Bon évidemment, ça ne fonctionne pas.
Premier problème, la classe WWW est deprecated.
Bon c'est pas grave, ils nous disent qu'on peut la remplacer par la classe UnityWebRequest.
Ok.
Sauf que UnityWebRequest c'est un peu relou parce qu'il faut l'utiliser dans une coroutine. C'est un peu chiant mais allons-y. Du coup le code devient un truc comme ça :
Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public LoadAudioFile(AudioSource sound)
{
    Action<AudioClip> callback = delegate (AudioClip clip)
    {
        if (clip != null)
           sound.clip = clip;
    };
 
    LoadClip("file://C:/mon/son/qui/tue.wav", AudioType.WAV, callback);
}
 
private void LoadClip(string path, AudioType audio_type, Action<AudioClip> callback)
{
    StartCoroutine(LoadAudioClipFromUrl(path, audio_type, (audioClip) =>
    {
        if (audioClip != null)
        {
            callback.Invoke(audioClip);
        }
    }));
}
 
IEnumerator private LoadAudioClipFromUrl(string audio_url, AudioType audio_type, Action<AudioClip> callback)
{
    using (UnityEngine.Networking.UnityWebRequest www = UnityEngine.Networking.UnityWebRequestMultimedia.GetAudioClip(audio_url, audio_type))
    {
        while (!www.isDone)
            System.Threading.Thread.Sleep(100);
 
        yield return www.SendWebRequest();
 
        if (www.isNetworkError)
            Debug.Log(string.Format("Error downloading audio clip at {0} : {1}", audio_url, www.error));
 
        callback.Invoke(UnityEngine.Networking.DownloadHandlerAudioClip.GetContent(www));
    }
 }

Bon ok, c'est vachement de code pour pas grand chose mais soit.
Sauf que ...
Si le fichier qu'on veut charger n'existe pas, ben on est bloqué dans une boucle infinie et c'est pas beau à voir. Même alt+F4 ne nous sauve pas toujours.
Bon ok, alors on ajoute des timeout et nbTry... et on gère tous les cas bizarres où le Network est "buzy"... oui parce que je vous rappelle que ce qu'on fait là, c'est une requête GET de type HTTP ... enfin bref...

Après avoir bien blindé le code, ça semble fonctionner. Dans l'éditeur en tout cas. C'est quand même relou : tout ça pour charger un pauvre fichier audio... enfin bref ...

Maintenant voyons voir ce que ça donne en stand alone.

Hé bien là, figurez-vous, c'est le drame ! Les requêtes http partent dans le vide interstellaire et sont incapables de trouver un foutu fichier local !
Même avec le path codé en dur, rien à faire : vous vous mangez des 404 dans le museau; l'enfer de Dante est une sinécure à côté.
Et votre beau fichier de log, que vous avez maintenu parfaitement propre avec la plus grande fierté depuis le début du projet, à tel point que lorsque le boss commence à péter une durite, seuls ces magnifiques fichiers de logs peuvent le calmer. Et bien vos beaux fichiers de logs, ben là ils sont complètement fuckés, parce que des requêtes http qui n'aboutissent pas, ben ça en fout partout !

Du coup, ben là c'est moi qui commence à pèter une durite. Et encore, ce n'est que le début ...

Envoyer le billet « Journal d'un développeur ivre : L'enfer de l'audio dans Unity #1 » dans le blog Viadeo Envoyer le billet « Journal d'un développeur ivre : L'enfer de l'audio dans Unity #1 » dans le blog Twitter Envoyer le billet « Journal d'un développeur ivre : L'enfer de l'audio dans Unity #1 » dans le blog Google Envoyer le billet « Journal d'un développeur ivre : L'enfer de l'audio dans Unity #1 » dans le blog Facebook Envoyer le billet « Journal d'un développeur ivre : L'enfer de l'audio dans Unity #1 » dans le blog Digg Envoyer le billet « Journal d'un développeur ivre : L'enfer de l'audio dans Unity #1 » dans le blog Delicious Envoyer le billet « Journal d'un développeur ivre : L'enfer de l'audio dans Unity #1 » dans le blog MySpace Envoyer le billet « Journal d'un développeur ivre : L'enfer de l'audio dans Unity #1 » dans le blog Yahoo

Mis à jour 25/11/2020 à 00h46 par r0d

Tags: audio, csharp, unity
Catégories
DotNET , C# , 2D / 3D / Jeux

Commentaires