Aller au contenu
Top-Metin2.org - Vous êtes à la recherche d'un serveur Metin 2 ? ×
×
×
  • Créer...
  • 0

[RESOLU] Jouer une webradio avec Miles Sound System


Ioio

Question

Version des fichiers/ Type d'émulateur : 40k

Domaine (Base de données, Client, Core...) : Sources client

Votre niveau (Débutant, Intermédiaire, Avancé..) : Intermédiaire

 

Description du problème : Bonjour, Alors voilà, cela fait plusieurs jours que je me penche sur ce casse-tête. Je voudrais savoir s'il est possible de lire un flux audio provenant d'internet (Par exemple: http://bbcwssc.ic.llnwd.net/stream/bbcwssc_mp1_ws-einws BBC London) avec les bibliothèques déjà présentes dans les sources. Je peux me tromper mais je suis sûr que cela est faisable en mélangeant un peu de créativité, boost et le système audio de Miles.

L'objectif c'est que la fonction PlayMusic ou FadeInMusic fonctionnent aussi bien avec des url qu'avec des fichiers wav. (Le code cpp doit faire le travail de les distinguer et d'agir en conséquence).

 

Comment reproduire le problème ? : Essayez d'implanter une webradio dans le jeu sans utiliser le navigateur intégré...

Recherches et tests effectués :

Aucune documentation pour le système Miles... Au passage si quelqu'un en a une je suis preneur.

Peut-être faudrait-il ajouter une bibliothèque genre libvlc etc ? (J'arrive même pas à faire un hello world avec ça)

Recherche d'un projet opensource qui ferait la même chose pour voir comment ils font et copier... introuvable (ou alors je ne sais pas chercher)

Pyaudio - fonctionne pas...

Boost: recherches en cours...

https://www.developpez.net/forums/d573877/c-cpp/c/reseau/lire-enregistrer-streaming-http/

 

 

En postant ma demande d'aide, j'affirme avoir lu et accepté le Règlement de Funky-Emulation.

Modifié par Ioio
Lien vers le commentaire
Partager sur d’autres sites

  • Réponses 16
  • Créé
  • Dernière réponse

Meilleurs contributeurs dans cette question

Meilleurs contributeurs dans cette question

16 réponses à cette question

Messages recommandés

  • 0

Salut, 

 

Garde à l'esprit que la version de Miles utilisée par MT2 date de 2002. 

J'ai regardé la doc, rien n'existe pour lire des flux internet directement, tu dois, je pense, lire directement le flux depuis une autre bibliothèque et créer un son avec Miles avec le buffer contenant les données du flux. 

Lien vers le commentaire
Partager sur d’autres sites

  • 0

Oui Kijaru, c'est à ça que je pensais...

Donc il faut ouvrir un thread pour mettre en cache l'audio provenant du flux sous forme de fichiers tmp-1.mp3 | tmp-2.mp3 | tmp-3.mp3. (Sectionner tous les blocs en 64kbits dans le cas d'un flux 64k)

C'est fichiers sont lus par Miles normalement comme s'il s'agissait d'une musique et seront supprimés au fur et à mesure... (autre thread pour gérer ça)

arrivé à tmp-9.mp3, on recommenca à tmp-1.mp3...

 

Logiquement la mise en cache se fait dans la RAM... Mais là je ne vois pas comment lire du son à partir de la RAM avec Miles...

 

 

Lien vers le commentaire
Partager sur d’autres sites

  • 0

Normalement tu n'a meme pas besoin de passer par des fichiers, tu peux simplement passer par un buffer. 

Je suis pas chez moi, mais il y a bien une fonction pour lire des sons depuis la mémoire, explore le .hpour trouver la fonction :)

Lien vers le commentaire
Partager sur d’autres sites

  • 0

Tu ne saurais pas pourquoi AIL_open_stream() me retourne un pointer null quand j'essaye au travers d'un bête programme console win32

 

C'est possible de jouer du son dans un programme console ?

 

 

C'est bon, résolu...

Modifié par Ioio
Lien vers le commentaire
Partager sur d’autres sites

  • 0

Le problème de son dans la console... En fait, mss fait jouer le son en mode async et ne bloque pas l'exécution du script... Ce qui fait que j'ai dû faire une boucle 

	while (AIL_stream_status(hStream) != -1)
	{
		printf("Status: %d", AIL_stream_status(hStream));
		cin.ignore();
	}

Dans mon programme.

Lien vers le commentaire
Partager sur d’autres sites

  • 0

Je ne trouve pas la manière de lire à partir de la RAM (buffer), ça m'aurait simplifié la vie...

 

Voilà où j'en suis:

J'ai réussi à faire un environnement console provisoire (limité à Windows)  pour lire un buffer de 64kb de la radio en boucle.

Ce code me servira juste à tester les différentes fonctions de mss....

Quand j'aurais trouvé des manières d'optimiser et de rendre ce code fonctionnel (pour lire la radio en continu), il me restera encore tout le travail de l'adapter à metin...

// MilesSysTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <Windows.h>
#include <WinInet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define HTTP_USER_AGENT "httprip"
#define BUFFER_SIZE 64000

using namespace std;

void usage(void);

int InternetSaveFile(const char *, const char *);
HSTREAM openFile(const char *);
void playRadio(HSTREAM);

HDIGDRIVER ms_DIGDriver = NULL;

int _tmain(int argc, _TCHAR* argv[])
{
	FILE *input = NULL;
	char buffer[BUFFER_SIZE] = { 0 };
	const char url[] = "http://bbcwssc.ic.llnwd.net/stream/bbcwssc_mp1_ws-einws";
	
	
	AIL_set_redist_directory("miles");
	AIL_startup();

	// Initialize MSS
	ms_DIGDriver = AIL_open_digital_driver(44100, 16, 2, 0);

	// Play Sound of pointer
	InternetSaveFile(url, "tmp.mp3");
	//playRadio(hStream);


	return 0;
}

int InternetSaveFile(const char *requesturl, const char *outputfile)
{
	const char http[] = "HTTP";
	HANDLE file;
	SECURITY_ATTRIBUTES sa;
	HINTERNET internet;
	HINTERNET url;
	char *buf = NULL;
	DWORD bytesread;
	DWORD byteswritten;
	int k;

	// validate protocol -- first 4 alphas should be http, case insensitive
	for (k = 0; k < 4; k++)
	if (requesturl[k] != http[k] && requesturl[k] != (char)(http[k] + 32))
		return 0;

	file = CreateFile(outputfile,
		GENERIC_WRITE,
		FILE_SHARE_READ,
		NULL,
		CREATE_ALWAYS,
		FILE_ATTRIBUTE_NORMAL,
		NULL);
	if (file == INVALID_HANDLE_VALUE)
		return 0;

	internet = InternetOpen(HTTP_USER_AGENT,
		INTERNET_OPEN_TYPE_PRECONFIG,
		NULL,
		NULL,
		0);
	if (internet == NULL)
		return 0;

	url = InternetOpenUrl(internet,
		requesturl,
		NULL,
		0,
		INTERNET_FLAG_PRAGMA_NOCACHE,
		0);
	if (url == NULL)
		return 0;

	buf = (char *)malloc(BUFFER_SIZE + 1);

	if (buf == NULL)
		return 0;

	if (InternetReadFile(url,
		buf,
		BUFFER_SIZE,
		&bytesread))
	{
		//if (bytesread == 0) break;


		WriteFile(file,
			buf,
			bytesread,
			&byteswritten,
			NULL);

	}

	free(buf);
	InternetCloseHandle(url);
	InternetCloseHandle(internet);
	CloseHandle(file);

	HSTREAM hStream = AIL_open_stream(ms_DIGDriver, "tmp.mp3", 0);
	if (hStream == NULL)
	{
		printf("Null Pointer buf: %d", bytesread);
		//break;
	}
	playRadio(hStream);

	return 1;
}

void playRadio(HSTREAM hStream)
{
	printf("Pointer: %p", hStream);
	AIL_set_stream_volume_levels(hStream, 1.0f, 1.0f);

	AIL_set_stream_loop_count(hStream, 0);
	AIL_start_stream(hStream);

	while (AIL_stream_status(hStream) != -1)
	{
		continue;
		Sleep(20);
	}
}

 

Lien vers le commentaire
Partager sur d’autres sites

  • 0
  • Développeur
Il y a 10 heures, Ioio a dit :

Oui Kijaru, c'est à ça que je pensais...

Donc il faut ouvrir un thread pour mettre en cache l'audio provenant du flux sous forme de fichiers tmp-1.mp3 | tmp-2.mp3 | tmp-3.mp3. (Sectionner tous les blocs en 64kbits dans le cas d'un flux 64k)

C'est fichiers sont lus par Miles normalement comme s'il s'agissait d'une musique et seront supprimés au fur et à mesure... (autre thread pour gérer ça)

arrivé à tmp-9.mp3, on recommenca à tmp-1.mp3...

 

Logiquement la mise en cache se fait dans la RAM... Mais là je ne vois pas comment lire du son à partir de la RAM avec Miles...

 

 

 

Ouch ça fait mal à mon disque dur rien que de lire ça...

Deux threads séparés pour écrire et supprimer du disque ça pique question perf.

 

Je pense que tu devrais plutôt te pencher sur WASAPI...
https://docs.microsoft.com/fr-fr/windows/desktop/CoreAudio/wasapi

Modifié par Kameyu
Lien vers le commentaire
Partager sur d’autres sites

  • 0

Je souhaite garder la structure de metin2, pour pouvoir éventuellement faire un tutoriel simple une fois que j'aurais trouvé la solution...

J'ai trouvé un projet intéressant dans lequel on peu avoir les sources de Miles 7.1a, une version 5 ans plus récente que celle actuellement présente dans les sources metin2:

https://bitbucket.org/Ryfon/mux/src/6c18d5efe8f426adf61ef189e73b5a0f6ef17ed4/Common/MilesWin/?at=master

Enjoy !

Lien vers le commentaire
Partager sur d’autres sites

  • 0
  • Développeur

Justement, c'est ça que je comprends pas.

 

Il sera plus simple d'utiliser directement WASAPI en l'intégrant à notre projet plutôt que de passer par un thread qui crée tes fichiers audio

puis utiliser ça avec Miles pour ensuite réutiliser un thread séparé pour s'occuper de la gestion des fichiers temporaires...

 

C'est un peu trop casse-tête pour pas grand chose, alors que t'as une solution à portée de mains et pas très compliquée à utiliser.

C'est littéralement: "Pourquoi faire simple quand on peut faire compliqué ?"

Lien vers le commentaire
Partager sur d’autres sites

  • 0

Je n'ai pas été formé à utilisé la doc microsoft... Je la trouve assez complexe... A chaque fois que j'essaye un de leur exemple je dois passer par des heures intenses de debug...

 

Etat d'avancement de la situation: Je pense avoir mis la main sur les fonctions me permettant de lire un flux directement à partir de la mémoire... J'ai donc enlevé toute la partie "fichier temporaire". Cependant, le code ne génère que du bruit pendent quelques secondes avant de fermer... Je dois encore déug...

#include "stdafx.h"
#include <Windows.h>
#include <WinInet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define HTTP_USER_AGENT "httprip"
#define BUFFER_SIZE 32000

using namespace std;

void usage(void);

int open_url_stream(const char *);

HDIGDRIVER ms_DIGDriver = NULL;

int _tmain(int argc, _TCHAR* argv[])
{
	const char url[] = "http://bbcwssc.ic.llnwd.net/stream/bbcwssc_mp1_ws-einws";
	
	// Initialize MSS
	AIL_set_redist_directory("miles");
	AIL_startup();
	ms_DIGDriver = AIL_open_digital_driver(44100, 16, 2, 0);
	
	open_url_stream(url);


	return 0;
}

int open_url_stream(const char *requesturl)
{
	const char http[] = "HTTP";
	HINTERNET internet;
	HINTERNET url;
	char *buf = NULL;
	DWORD bytesread;
	DWORD byteswritten;
	int k;

	// validate protocol -- first 4 alphas should be http, case insensitive
	for (k = 0; k < 4; k++)
	if (requesturl[k] != http[k] && requesturl[k] != (char)(http[k] + 32))
		return 0;

	internet = InternetOpen(HTTP_USER_AGENT,INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0);
	if (internet == NULL)
		return 0;
	url = InternetOpenUrl(internet,requesturl,NULL,0,INTERNET_FLAG_PRAGMA_NOCACHE,0);
	if (url == NULL)
		return 0;

	buf = (char *)malloc(BUFFER_SIZE + 1);

	if (buf == NULL)
		return 0;

	HSAMPLE smp = AIL_allocate_sample_handle(ms_DIGDriver);
	AIL_init_sample(smp, DIG_F_STEREO_16, 0);
	AIL_set_sample_playback_rate(smp, 44100);
	U32 lastupdate = 0;

	while (InternetReadFile(url,buf,BUFFER_SIZE,&bytesread))
	{
		AIL_set_sample_address(smp, buf, BUFFER_SIZE);
		printf("Buf: %p\r", buf);
		AIL_start_sample(smp);

		AIL_delay(1);

		if ((AIL_ms_count() - lastupdate) > 1000)
		{
			printf("\r  CPU: %i %% (%i samples playing)   ", 
				AIL_digital_CPU_percent(ms_DIGDriver), 
				AIL_active_sample_count(ms_DIGDriver));
			lastupdate = AIL_ms_count();
		}
	}

	InternetCloseHandle(url);
	InternetCloseHandle(internet);
	free(buf);

	return 1;
}

 

Lien vers le commentaire
Partager sur d’autres sites

  • 0

Parfait, merci !

________________

 

Voilà, le système FMOD m'a permis de rapidement faire ce plugin sans en parallèle au système actuel du jeu...

 

Vous pourrez trouver le système dans les fichiers ci-dessous:

Hidden Content

    Give reaction to this post to see the hidden content.

 

NB: N'oubliez pas d'ajouter fmod_vc.lib au Linker (Clic droit sur User Interface dans la liste des projets -> Linker -> Input)

 

Merci Kijaru pour ta suggestion !

_________________________________

 

Idée d'amélioration du système: Ajouter snd.StopURLMusic() | Prendre en charge les erreurs->Syserr | Migrer tout le client de miles -> FMOD

__________________________________

Sujet résolu !

Modifié par Ioio
Résolu
Lien vers le commentaire
Partager sur d’autres sites

Invité
Ce sujet ne peut plus recevoir de nouvelles réponses.


  • brilliantdiscord_widget
  • Flux d'Activité

    1. 21

      Metin2 en 2020 peut-on en parler?

    2. 0

      METIN2Project

    3. 3

      Ressources - UnPack - Metin2 Client - Officiel

    4. 0

      Barre des tâches d'argent étendue

    5. 16

      Redémarrage automatique des channels

    6. 16

      Multi Logo GM / SGM / GA

  • En ligne récemment

    • Aucun utilisateur enregistré regarde cette page.

Information importante

Conditions d’utilisation / Politique de confidentialité / Règles / Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer.