Page 1 sur 1

Lire un flux radio sans fmodex (début d'hypothèse)

Publié : lun. 24/déc./2018 11:20
par Marc56
J'essaye de trouver un moyen pour lire les webradios sans utiliser la lib fmodex (bonne lib, mais qui fait 1,4 Mo et dont on utilise presque rien).

En écoutant en parallèle la radio et la diffusion par internet, je me suis rendu compte qu'il y avait une seconde de décalage.
Certaines radios sont de simples fichiers mp3 diffusés en continu.
Si on écoute un flux, et qu'on fait ctrl+s on obtient bien un fichier mp3.
Partant de là et sachant que PB lit les mp3 avec la lib movie, j'ai testé un truc.

Enregistrer quelques secondes puis les lire.
Programme très moche mais qui fonctionne et illustre le principe

Code : Tout sélectionner

InitNetwork()
 
OpenWindow(0, 0, 0, 500, 300, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
 
Tmp_FileName$ = GetTemporaryDirectory() + "FluxRadio.mp3"
Telechargement = ReceiveHTTPFile("http://direct.franceinter.fr/live/franceinter-midfi.mp3", Tmp_FileName$, #PB_HTTP_Asynchronous)

If Telechargement
    Repeat
        ; Charger 5 secondes de flux
        Delay(1000)
        i + 1
        If i = 6 : Break : EndIf
        Debug "Téléchargement en cours: " + HTTPProgress(Telechargement) + " octets reçus"
        Delay(500) ; Libérer le CPU
    ForEver
Else
    Debug "Erreur de téléchargement"
EndIf

AbortHTTP(Telechargement)
FinishHTTP(Telechargement)

Delay(1000)

InitMovie()

; Je ne sais pas pourquoi, mais impossible de réouvrir le fichier
; Donc copie et là ça fonctionne
Tmp_FileName2$ = GetTemporaryDirectory() + "WebRadio.mp3"
CopyFile(Tmp_FileName$, Tmp_FileName2$)

Debug Tmp_FileName2$
Debug FileSize(Tmp_FileName2$)
If LoadMovie(0, Tmp_FileName2$)
    PlayMovie(Read_Radio, WindowID(0))
    Delay(5000)
EndIf
Sur ce principe, je me suis dit qu'il devrait être possible à la fois d'enregistrer le fichier et de le lire par bloc.

Ici, je l'ai fait avec des fichiers car je manipule mal des downloads en mémoire.
Le problème est que le fichier interrompu est considéré comme non fermé et donc non lisible, c'est pourquoi je le recopie avant de le lire et ça marche.
J'ai pensé utiliser les fonction ReceiveNetworkData() il faut alors penser à créer le magic number pour créer l'entête mp3

:idea: Ce que je cherche à concrétiser serait donc de lire le flux par petits blocs d'une secondes puis de le lire en tant que fichier avec movie

Hypothèse 1: "tailler" le début du fichier fichier au fur et à mesure de l'avance en lecture
Hypothèse 2: Faire une succession de petits fichiers lus les uns après les autres (mais gérer l'eventuel bruit ou pause entre fichiers)

Si vous avez des suggestions, idées ?
Si ça fonctionne ce serait l'occasion d'une fonction qui pourrait être ajouté à la lib movie.

:wink:

Re: Lire un flux radio sans fmodex (début d'hypothèse)

Publié : lun. 24/déc./2018 13:06
par Ollivier
Bonjour Marc56,

je doute que ce soit faisable.

Difficulté : entre la commande de téléchargement émise côté client, et la commande de transfert reçue côté serveur, il y a une durée variable. Ton idée serait possible si le serveur émettait des fichiers avec des méta-données de l'heure précise de diffusion. Avec ça, tu pourrais synchroniser le démarrage d'un son.

Si tu trouves de telles méta-données, alors... Alors !

Re: Lire un flux radio sans fmodex (début d'hypothèse)

Publié : mer. 26/déc./2018 12:28
par Zorro
@Marc56 ...

je suis passé sur le Forum histoire de voir ce qu'il deviens et probablement par un reflexe conditionné , je ne suis pas de retour , je precise ...
mais lorsque je lis qu'un truc est sois disant impossible ou pas faisable .. , :roll:
Bonjour Marc56,

je doute que ce soit faisable.


ç'est plus fort que moi ...:lol:

voici une façon de lire un flux mp3 en utilisant juste le Web editor et un peut de code Html5 ...
comme le navigateur sur windows10 et Purebasic ne semble pas fonctionner, j'utilise une procedure pour forcer l'utilisation d'un navigateur compatible Html5
en fait celui de Windows10 .. (voir le contenu de la procedure pour comprendre )

Code : Tout sélectionner


;***********************************************
;Titre  :*lecteur_de_web_radio2
;Auteur  : Zorro
;Date  :26/12/2018
;Heure  :12:21:06
;Version Purebasic :  PureBasic 5.42 LTS (Windows - x86)
;Version de l'editeur :EPB V2.68
; Libairies necessaire : Aucune 
;***********************************************

Declare setbrowseremulation() ; permet de choisir le type de navigateur qu'on veux

Enumeration
		#Win 
		#web
Endenumeration

Adresse_Flux_mp3$="http://direct.franceinter.fr/live/franceinter-midfi.mp3" ; adresse a lire


html5$="<!DOCTYPE html>"+chr(10) 
html5$+"<html lang="+chr(34)+"fr"+chr(34)+">"+chr(10) 
html5$+"<head>"+chr(10)
html5$+"<title>HTML5</title>"+chr(10) 
html5$+"<meta charset="+chr(34)+"UTF-8"+chr(34)+">"+chr(10)
html5$+chr(10)
html5$+"<style>"+chr(10) 
html5$+"fieldset { border : 2px solid #4040A4;"+chr(10)
html5$+"   width : 550px;}"+chr(10) 
html5$+"span {margin-right:24px;}"+chr(10)
html5$+"</style>"+chr(10)
html5$+chr(10)
html5$+"</head>"+chr(10) 
html5$+"<body>"+chr(10) 
html5$+chr(10)
html5$+"<audio controls preload>"+chr(10)
html5$+"<source src="+chr(34)+Adresse_Flux_mp3$+chr(34)+">"+chr(10) 
html5$+" Votre navigateur ne supporte pas la balise audio. </audio> "
html5$+chr(10)
html5$+"<footer>"+chr(10) 
html5$+"<hr> "+chr(110)
html5$+"<p>By Dobro  ;) </p>"+chr(10)  
html5$+"</footer> "+chr(10)
html5$+"</body>"+chr(10) 
html5$+"</html>"+chr(10)



SetBrowserEmulation()  ; choisi une version du navigateur


If OpenWindow(#win,0,0,600,300,"WebGadget",#PB_Window_SystemMenu | #PB_Window_ScreenCentered) 
		WebGadget(#web,10,10,580,280,"")
		; Note: si vous désirez utiliser un fichier local, changez le dernier paramètre en "file://" + chemin + nomdufichier
		SetGadgetItemText(#web,#PB_Web_HtmlCode ,html5$)
		
		
		Repeat 
		Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf



;-- Zone Procedures 
Procedure SetBrowserEmulation() ; permet de choisir le type de navigateur qu'on veux
		
		; https://msdn.microsoft.com/en-us/library/ee330730(v=vs.85).aspx
		
		Protected IEVersion.s = "2AF9" ; setting the desired IE-Version (see below)
		
		; 11001 (0x2AF9) IE11. Webpages are displayed in IE11 edge mode, regardless of the declared !DOCTYPE directive. Failing to declare a !DOCTYPE directive causes the page to load in Quirks.
		; 11000 (0x2AF8) IE11. Webpages containing standards-based !DOCTYPE directives are displayed in IE11 edge mode. Default value for IE11.
		; 10001 (0x2711) IE10. Webpages are displayed in IE10 Standards mode, regardless of the !DOCTYPE directive.
		; 10000 (0x2710) IE10. Webpages containing standards-based !DOCTYPE directives are displayed in IE10 Standards mode. Default value for IE 10.
		;  9999 (0x270F) IE9.  Webpages are displayed in IE9 Standards mode, regardless of the declared !DOCTYPE directive. Failing to declare a !DOCTYPE directive causes the page to load in Quirks.
		;  9000 (0x2328) IE9.  Webpages containing standards-based !DOCTYPE directives are displayed in IE9 mode. Default value for IE 9. Important  In IE 10, Webpages containing standards-based !DOCTYPE directives are displayed in IE10 Standards mode.
		;  8888 (0x22B8) IE8.  Webpages are displayed in IE8 Standards mode, regardless of the declared !DOCTYPE directive. Failing to declare a !DOCTYPE directive causes the page to load in Quirks.
		;  8000 (0x1F40) IE8.  Webpages containing standards-based !DOCTYPE directives are displayed in IE8 mode. Default value for IE 8 Important  In IE 10, Webpages containing standards-based !DOCTYPE directives are displayed in IE10 Standards mode.
		;  7000 (0x1B58) IE7.  Webpages containing standards-based !DOCTYPE directives are displayed in IE7 Standards mode. Default value for applications hosting the WebBrowser Control. 
		
		Protected RegistryString.s
		Protected TempRegFile.s
		Protected FF
		
		RegistryString = "Windows Registry Editor Version 5.00" + #CRLF$ +
		"" + #CRLF$ +
		"[HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION]" + #CRLF$ +
		Chr(34) + GetFilePart(ProgramFilename()) + Chr(34) + "=dword:" + IEVersion + #CRLF$
		
		TempRegFile = GetTemporaryDirectory() + "SetBrowserEmulation.reg"
		
		FF = CreateFile(#PB_Any, TempRegFile)
		
		If FF
				WriteString(FF, RegistryString)
		CloseFile(FF)
		RunProgram("regedit", "/s " + Chr(34) + TempRegFile + Chr(34), "", #PB_Program_Hide | #PB_Program_Wait)
		DeleteFile(TempRegFile)
		ProcedureReturn #True
EndIf
EndProcedure


allez .. je retourne dans "No man's Sky" , et sur l'etude du C# avec Unity ...ainsi que la vision de Unreal engine ... c'est dingue ce qu'on peut faire
en dehors de Purebasic ...

pour les curieux , n'hesitez pas a utiliser c# , lorsqu'on viens du Purebasic, c'est tres simple a comprendre ;)

joyeux noel, et bonne années les gens :)

Re: Lire un flux radio sans fmodex (début d'hypothèse)

Publié : mer. 26/déc./2018 14:55
par G-Rom
Marc56 a écrit : Hypothèse 1: "tailler" le début du fichier fichier au fur et à mesure de l'avance en lecture
Hypothèse 2: Faire une succession de petits fichiers lus les uns après les autres (mais gérer l'eventuel bruit ou pause entre fichiers)

Si vous avez des suggestions, idées ?
Si ça fonctionne ce serait l'occasion d'une fonction qui pourrait être ajouté à la lib movie.

:wink:
Bonjour Marc, ton hypothèse est une partie de la bonne solution.
- si ton fichier est hébergé sur un site web, une requete html via les commandes network suffira pour obtenir le flux d'un fichier mp3.
- ton flux étant incomplet, car un mp3 peut être gros, tu devras stocker ce début de fichier en mémoire ( le tampon )
- il te faudra décodé le mp3 a la main, chaque mp3 de mémoire possède des "frames" , il te faut 9 frames pour pouvoir décoder le contenu
- tu génère à la mano un son wave , que tu remplis avec le mp3 préalablement décodé, l'ideal est d'avoir aussi un "ring buffer" que tu lis en permanence et que tu remplis au fur & à mesure du décodage.

C'est compliqué , car il faut géré plusieurs domaine , les requête html pour obtenir le fichier en partie ( la fonction ne doit pas être bloquante ) , le décodage, la creation d'un fichier wav en mémoire pour la lecture du mp3.

https://en.wikipedia.org/wiki/MP3#File_structure
http://www.mp3-tech.org/programmer/frame_header.html


Zorro a écrit :pour les curieux , n'hesitez pas a utiliser c# , lorsqu'on viens du Purebasic, c'est tres simple a comprendre
La vache, tu est devenu "ouvert" ?? Regarde le godot engine, il supporte le C# maintenant en plus du gdscript ( ainsi que le c++ ) ou même purebasic via les dll.

Re: Lire un flux radio sans fmodex (début d'hypothèse)

Publié : mer. 26/déc./2018 16:06
par Marc56
Bonjour Zorro, content de te revoir parmi nous pour sortir ce forum de son endormissement et de sa transformation en métamoteur humain de google et du forum purebasic us :( . Tes codes -originaux- bien documentés et -expériences- sont un des piliers de ces forums.

Oui, cette idée est intéressante, et fonctionne très bien, mais elle a deux inconvénients: la taille en RAM (3x+) due à la nécessité d'utiliser un moteur html autre que le webgadet (qui ne lit pas) et il en découle la nécessité de modifier la base de registre (ce que fait ton exemple avec regedit /s). Mais je ne souhaite pas (mes utilisateurs n’aiment pas qu'on touche à la base de registre).

Merci G-Rom, cela semble compliqué, je pensais cela plus simple, mais je vais me pencher dessus. Tout est possible en PB puisqu'on gère facilement les fichiers binaires et j'ai pu faire un truc en lecture binaire pour détecter la rotation des fichiers images en fonction des exifs alors que n'y connaissais pas grand chose. Merci pour les liens.

Oui, j'ai aussi fait du C++ (pas du C#) et autres "joyeusetés", mais au final, je reviens toujours à PB car c'est le seul langage productif (pour mon usage), c'est à dire que je passe 99% de mon temps sur mon programme (1% pour la touche F1) alors qu'avec d'autres, si je compte objectivement, je passais 50% à chercher des libs, de la doc, d'autres libs (obsolètes), des libs (buggués) pas à jour, des libs compatibles et me battre avec des pointeurs et autres choses "logiques" et documentation inexistante et finalement, à part chercher et découvrir, je ne faisais (presque) rien de réellement utilisable : :) :mrgreen: :!:

:wink:

Re: Lire un flux radio sans fmodex (début d'hypothèse)

Publié : jeu. 27/déc./2018 9:56
par Zorro
autre version , plus cours, t'es mort ;)

Code : Tout sélectionner


; plus court , tu meurs 
Adresse_Flux_mp3$="http://direct.franceinter.fr/live/franceinter-midfi.mp3" ; adresse a lire
 Compilateur = RunProgram(Adresse_Flux_mp3$, "/?", "")
 
bon ... je m'arrete la, j'ai pas vocation a recoder en Pb :) a+++ et bonne Année :)

Re: Lire un flux radio sans fmodex (début d'hypothèse)

Publié : jeu. 27/déc./2018 13:17
par MLD
Salut Zorro
J'ai un réel plaisir a te revoir ici
Bonne année a toi

Re: Lire un flux radio sans fmodex (début d'hypothèse)

Publié : jeu. 27/déc./2018 17:25
par Zorro
Merci :)

allez come j'aime bien finir le boulot , voici la suite

en utilisant Firefox via Run prg

Code : Tout sélectionner

; plus court , tu meurs
Adresse_Flux_mp3$="http://direct.franceinter.fr/live/franceinter-midfi.mp3" ; adresse a lire
Compilateur = RunProgram(Adresse_Flux_mp3$, "/?", "")
le problem c'est que le navigateur reste en affichage , alors voici comment ruser ...
j'utilise 2 fonctions (ou partie de fonction de mon ancienne "lib Hacker"

pour recuperer le PID et le Handle du navigateur ,ça permet ensuite de pouvoir cacher au lancement
et de le killer lorsqu'on appuis sur le bouton STOP ...

ça peut faire illusion a condition de disposer de Firefox , je pense qu'on peut surement faire la meme chose avec EDGE ou Internet explorer
il faudrai cibler en fonction du systeme d'exploitation utilisé par l'user ...
ça reste quand meme de la bidouille ; perso je prefere utiliser une lib toute faite ... mais bon c'etait le challenge soulevé
faire un lecteur de Radio sans utiliser de librairie ... :)

c'est une soluce comme une autre :) ... voila je ne vous derange plus


PS si chez vous ça ne marche pas c'est que soit vous n'avez pas Firefox
soit il faut augmenter les Delays du code ... sur certains ordi ça peut etre plus long a demarrer :)

Code : Tout sélectionner


;***********************************************
;Titre  :*lecteur_de_web_radio4
;Auteur  : Zorro
;Date  :27/12/2018
;Heure  :17:28:24
;Version Purebasic :  PureBasic 5.42 LTS (Windows - x86)
;Version de l'editeur :EPB V2.68
; Libairies necessaire : Aucune 
;***********************************************


Declare openwindow_win()
Declare.l cheater_pid_return(gamewindowtext.s)




#SW_FORCEMINIMIZE=11
; plus court , tu meurs
Global Adresse_Flux_mp3$
Global Flag ; determine si le flux est en lecture
Global Pid ; l'id du navigateur qui sert a lire le mp3
;{- Enumerations / DataSections
;{ Windows
Enumeration
		#Win
EndEnumeration
;}
;{ Gadgets
Enumeration
		#Text_0
		#Button_Play
		#Button_Stop
		#String_Adresse
EndEnumeration
;}
;{ Fonts
Enumeration
		#Font_Text_0
EndEnumeration


; ************* pour le PID *****************
Structure PROCESSENTRY33
		dwSize.L
		cntUsage.L
		th32ProcessID.L
		th32DefaultHeapID.L
		th32ModuleID.L
		cntThreads.L
		th32ParentProcessID.L
		pcPriClassBase.L
		dwFlags.L
		szExeFile.b[#MAX_PATH]
EndStructure
;**************************************




;}
Define.l Event
;}
Procedure OpenWindow_Win()
		If OpenWindow(#Win, 550, 157, 507, 260, "Radio a 2 balles", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
				
				TextGadget(#Text_0, 90, 0, 270, 40, "Radio a 2 balles", #PB_Text_Center)
				ButtonGadget(#Button_Play, 30, 110, 90, 40, "Play")
				ButtonGadget(#Button_Stop, 30, 170, 90, 40, "Stop")
				StringGadget(#String_Adresse, 80, 50, 360, 30, "http://direct.franceinter.fr/live/franceinter-midfi.mp3")
				Adresse_Flux_mp3$=GetGadgetText(#String_Adresse)
				; Gadget Fonts
				SetGadgetFont(#Text_0, LoadFont(#Font_Text_0, "Microsoft Sans Serif", 18, #PB_Font_Bold|#PB_Font_HighQuality))
				
		EndIf
EndProcedure

OpenWindow_Win()

;{- Event loop
Repeat
		Event = WaitWindowEvent(12)
		Select Event
				; ///////////////////
				Case #PB_Event_Gadget
				Select EventGadget()
						Case #Text_0
						Case #Button_Play
						Compilateur = RunProgram(Adresse_Flux_mp3$, "", "",#PB_Program_Hide)
						delay(5000) ; le temps de lancer Firefox ... 
						hWin= FindWindow_(#Null, "franceinter-midfi.mp3 - Mozilla Firefox" ) ; on recherche si une fenetre ayant pour titre "hello" .....existe oui ??   ;franceinter-midfi.mp3 - Mozilla Firefox
						delay(3000) ; le temps de recup le handle...
						ShowWindow_(hWin, #SW_HIDE) ; on cache la fenetre du navigateur (Bidouille LOL )
						; a partir de la ça doit jouer normalement
							Pid=cheater_pid_return("Firefox.exe")				
						
						Flag=#true
						Case #Button_Stop
						If Flag=#True
								ShowWindow_(hWin,#SW_SHOW) ; on remontre la fenetre qu'on avait caché ...				
								phandle = OpenProcess_ ($1, #False, pid)
								If phandle <> #Null
										If TerminateProcess_ (phandle, 1)
												result = #True
										EndIf
										CloseHandle_ (phandle)
								EndIf
								Flag=#False
						Endif
						Case #String_Adresse
						Adresse_Flux_mp3$=GetGadgetText(#String_Adresse) ; pour que ceci fonctionne  il faut analyser ce qui est entré , et prendre que la derniere partie du lien pour lui ajouter " - Mozilla Firefox" (voir ligne 81)
						
				EndSelect
				; ////////////////////////
				Case #PB_Event_CloseWindow
				Select EventWindow()
						Case #Win
						CloseWindow(#Win)
						Break
				EndSelect
		EndSelect
Forever
;
;}





;- Zone Procedures

ProcedureDLL.L cheater_pid_return(gamewindowtext.s)
		; Laisse cette procedure au dessus des autres, car elle est appelé par les autres
		Name.s=UCase(gamewindowtext.s)
		Recherche=0
		If OpenLibrary(0, "Kernel32.dll")
				CreateToolhelpSnapshot = GetFunction(0, "CreateToolhelp32Snapshot")
				ProcessFirst           = GetFunction(0, "Process32First")
				ProcessNext            = GetFunction(0, "Process32Next")
				If CreateToolhelpSnapshot And ProcessFirst And ProcessNext ; Ensure than all the functions are found
				Process.PROCESSENTRY33\dwSize = SizeOf(PROCESSENTRY33)
				Snapshot = CallFunctionFast(CreateToolhelpSnapshot, #TH32CS_SNAPPROCESS, 0)
				If Snapshot
						ProcessFound = CallFunctionFast(ProcessFirst, Snapshot, Process)
						While ProcessFound
								Nom.s=UCase(PeekS(@Process\szExeFile, -1, #PB_Ascii))
								Nom=GetFilePart(Nom)
								If FindString(Nom,Name.s,1);;=Name;If Nom=Name
										Recherche =1
										pid=Process\th32ProcessID
								EndIf
								ProcessFound = CallFunctionFast(ProcessNext, Snapshot, Process)
						Wend
				EndIf
				CloseHandle_(Snapshot)
		EndIf
		CloseLibrary(0)
EndIf
ProcedureReturn pid
EndProcedure




Re: Lire un flux radio sans fmodex (début d'hypothèse)

Publié : jeu. 27/déc./2018 17:49
par Marc56
c'est une soluce comme une autre :) ... voila je ne vous derange plus
Tsss, tsss vu le fort trafic qu'il y a sur ce forum, c'est sur que tu nous dérange :mrgreen:
Laisse tomber le C (#, ++ etc) il n'y a rien de fun à tirer de la programmation dans ce langage, c'est juste fait pour bosser (à condition d'être payé cher pour) et ça fait vendre de l'aspirine. :wink:
Repose ta tasse de café ici et code nous du vrai, from scratch comme tu sais faire. Tu as déjà fait pire avec des programmes de déformation d'image, un flux audio c'est un défi à ta hauteur et en tant que musicien ça doit t'intéresser 8)

Re: Lire un flux radio sans fmodex (début d'hypothèse)

Publié : jeu. 27/déc./2018 20:36
par Kwai chang caine
@DOBRO/SPOCK/ZORRO
Salut celui qui surgit hors de la nuuuuuuit !!!!, enfin plutôt hors du C# apparemment :mrgreen:

Je ne suis pas étonné de te relire....car "PB un jour ...PB toujours" tel est le dur tribut à payer à ce formidable langage 8)
Par contre je suis étonné d'être content de te lire :lol:

Qu'est ce que tu veux, on oublie pas un membre comme toi, les bons ou les mauvais moments restent quand même une bonne tranche de ma vie de scarabée 8)
Amuse toi bien avec le C#, mais tu sais au fond de toi, que tu auras toujours ta place ici....
Et pis intelligent comme tu es, t'es surement pas à court d'idées de nouveaux pseudos :lol: