Partie 1 : Introduction
Pour ce second article, je vais présenter comment réaliser un player de fichier M3U.
La plupart des WebRadios utilisent des liens portants sur des fichiers M3u. Voici la définition de wikipédia «M3U (MPEG version 3.0 URL) est un format de fichier qui a pour but de stocker une liste de fichiers audio ou vidéo.»
On voit donc qu’il fait parti des standards. Son étude sur android est donc intéressante. Malheureusement l’api mediaplayer d’Android n’est pas capable aujourd’hui de lire directement ce format. Voici donc un tutoriel montrant comment contourner ce problème.
Partie 2 : Architecture Technique
En voici son format : (Wikipédia
)
- défini par le mot clé : #EXTM3U
- puis #EXTINF: suivi de la durée du titre en secondes (ou de -1 pour ignorer la durée) et d’une virgule.
- le titre du morceau.
- Et à la ligne : l’URL ou le simple nom du fichier.
En regardant avec un éditeur de texte, un fichier M3u n’est d’autre que du texte. Si l’on arrive à partir d’un fichier à récupérer l’url, alors notre mediaplayer pourra lire notre radio. (çà devrait pas être compliqué)
Partie 3 : Conception applicative
Avant de rentrer directement dans le code, on va définir la page de notre application ainsi que la classe métier qui réalise notamment le parsing du fichier M3u …
En fin de partie nous aurons notre AndroidManisfest qui représente notre fichier de configuration des applications Android.
3.1 L’activity
Pour organiser correctement notre application, commencez par créer un package «com.projet.android». Celui-ci comprendra notre activity que voici :
| Nom | Layout Associé | Description |
| PlayerActivity | main.xml | page d’accueil |
3.2 La classe
Cette fois-ci un seul package sera utilisé «com.projet.android.metier».
| ParserM3UToURL | Classe métier qui gère la récupération de l’url dans le fichier M3U | com.projet.android.metier |
Comme promis voici le manifest.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <?xml version="1.0" encoding="utf-8"?> xmlns:android="http://schemas.android.com/apk/res/android" package="com.radio.reveil" android:versionCode="1" android:versionName="1.0" > android:minSdkVersion="10" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:label="@string/app_name" android:name=".PlayerActivity" > <intent-filter > android:name="android.intent.action.MAIN" /> android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> android:name="android.permission.INTERNET"> </manifest> |
Quelques explications :
On retrouve notre activité sous la baliseandroid ….>
L’application a besoin d’internet :
- Internet pour faire les requêtes android.permission.INTERNET
Voilà on vient de terminer notre conception. On passe maintenant au code…
Partie 4 : Code
On va commencer par l’ activity.
4.1 PlayerActivity.java
Voici la seule activity de notre projet. Je vous l’accorde, ce n’est pas très joli ![]()
Le but étant de simplifier afin de ne pas être perdu. ![]()
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175 package com.radio.reveil;
import java.io.IOException;
import com.radio.reveil.metier.ParserM3UToURL;
import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnInfoListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.DigitalClock;
import android.widget.ProgressBar;
import android.widget.TextView;
public class PlayerActivity extends Activity implements OnInfoListener,OnPreparedListener,OnErrorListener , OnCompletionListener{
@SuppressWarnings("unused")
private Button button_play;
@SuppressWarnings("unused")
private Button button_quit;
private ProgressBar progress_main;
private TextView text_info;
MediaPlayer mediaPlayer;
private Activity rootActivity;
private boolean isPlaying = false;
@SuppressWarnings("unused")
private DigitalClock digitalClock;
String STREAM_URI;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
Log.i("WakeUpRadio","Radio Starts");
// get are self
rootActivity = this;
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// get the UI elemntns
button_play = (Button) findViewById(R.id.start);
button_quit = (Button) findViewById(R.id.stop);
progress_main = (ProgressBar) findViewById(R.id.progressBar);
text_info = (TextView) findViewById(R.id.textInfo);
digitalClock = (DigitalClock)findViewById(R.id.digitalClock);
}
//Bouton PLay
public void Start(View v){
// Perform action on click
Log.v("FreshAir", "Play button pressed");
STREAM_URI = ParserM3UToURL.parse("http://streams.frequence3.net/mp3-192.m3u");
if (mediaPlayer == null) {
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnCompletionListener((OnCompletionListener) rootActivity);
mediaPlayer.setOnErrorListener((OnErrorListener) rootActivity);
mediaPlayer.setOnInfoListener((OnInfoListener) rootActivity);
mediaPlayer.setOnPreparedListener((OnPreparedListener) rootActivity);
try {
mediaPlayer.setDataSource(STREAM_URI);
} catch (IllegalArgumentException e) {
onError(mediaPlayer, -1, -1);
return;
} catch (IllegalStateException e) {
onError(mediaPlayer, -1, -1);
return;
} catch (IOException e) {
onError(mediaPlayer, -1, -1);
return;
}
try {
progress_main.setVisibility(View.VISIBLE);
mediaPlayer.prepareAsync();
text_info.setText("Loading ...");
isPlaying = true;
} catch (IllegalStateException e) {
onError(mediaPlayer, -1, -1);
}
}
}
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.v("FreshAir", "onError (" + what + ")");
if(mp != null){
mp.release();
mp = null;
}
isPlaying = false;
text_info.setText("Error: Please Retry");
progress_main.setVisibility(View.INVISIBLE);
return true; // return true to stop OS calling 'onCompletion'
}
@Override
public void onPrepared(MediaPlayer mp) {
try {
mediaPlayer.start();
} catch (IllegalStateException e) {
onError(mp, -1, -1);
}
text_info.setText("Playing ...");
progress_main.setVisibility(View.INVISIBLE);
}
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
// TODO: currently the getMetadata method is not present
Log.v("FreshAir", "onInfo (" + what + " - " + extra + ")");
switch (what) {
case 701: //MediaPlayer.MEDIA_INFO_BUFFERING_START:
text_info.setText("Buffering ...");
progress_main.setVisibility(View.VISIBLE);
isPlaying = true; // ie you cant re set the data sourse without
// stoping first
break;
case 702: //MediaPlayer.MEDIA_INFO_BUFFERING_END:
text_info.setText("Playing ...");
progress_main.setVisibility(View.INVISIBLE);
isPlaying = true;
default:
break;
}
return true; // return true to stop the OS calling 'onError'
}
@Override
public void onCompletion(MediaPlayer mp) {
if(mp == null)
return;
mp.release();
mp = null;
isPlaying = false;
progress_main.setVisibility(View.INVISIBLE);
}
// Stop button
public void Stop(View v){
if(isPlaying || (mediaPlayer != null && mediaPlayer.isPlaying())){
if(mediaPlayer.isPlaying()){
mediaPlayer.stop();
}
mediaPlayer.release();
mediaPlayer = null;
text_info.setText("");
isPlaying = false;
progress_main.setVisibility(View.INVISIBLE);
}
}
}
Maitenant le layout associé
4.2 main.xml
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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | <?xml version="1.0" encoding="utf-8"?> xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <ProgressBar android:id="@+id/progressBar" style="@android:style/Widget.ProgressBar.Small" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:padding="8dip" android:visibility="invisible" /> <TextView android:id="@+id/textInfo" android:text="info" android:layout_width="90dip" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_toLeftOf="@+id/progressBar" android:padding="8dip" /> <DigitalClock android:id="@+id/digitalClock" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/textInfo" android:layout_centerHorizontal="true" android:paddingTop="10dip" android:text="DigitalClock" android:textColor="#CC00FF" android:textSize="70dip" /> <Button android:id="@+id/start" android:layout_below="@+id/digitalClock" android:layout_width="90dip" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_marginTop="12dp" android:text="Start" android:onClick="Start" /> <Button android:id="@+id/stop" android:layout_below="@+id/start" android:layout_width="90dip" android:layout_height="wrap_content" android:layout_alignLeft="@+id/start" android:layout_marginTop="12dp" android:text="Stop" android:onClick="Stop" /> </RelativeLayout> |
4.3 ParserM3UToURL
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
38
39
40
41
42
43
44
45
46
47
48
49 package com.radio.reveil.metier;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class ParserM3UToURL {
/*
* Classe qui permet de retrouver l'url d'un flux
* à partir d'un fichier M3U
*/
public static String parse(String urlM3u) {
String ligne=null;
try {
URL urlPage = new URL(" http://streams.frequence3.net/mp3-192.m3u");
HttpURLConnection connection = (HttpURLConnection) urlPage.openConnection();
InputStream inputStream = connection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuffer stringBuffer = new StringBuffer();
while((ligne = bufferedReader.readLine()) != null) {
if (ligne.contains("http")){
connection.disconnect();
bufferedReader.close();
inputStream.close();
return ligne;
}
stringBuffer.append(ligne);
}
connection.disconnect();
bufferedReader.close();
inputStream.close();
}catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
Partie 5 : Conclusion
Voilà je pense que çà été pour ce tutoriel. Il n’est pas très long à reproduire.
Bon courage…







si on veut utiliser shoutcast pour le radio qu’est qu’on doit faire . merci
Sur ce site on trouve de l’aide sur leur API.
http://wiki.winamp.com/wiki/SHOUTcast_Radio_Directory_API
Visiblement cela permet de récuperer le lien d’un fichier .pls
Ce fichier semble être une playlist qu’il faudra aussi parser pour récupérer les lien à mettre dans le lecteur.
Bref je n’ai rien testé, je viens de trouver ses infos.
bon courage