Javowe FiXowanie – Let’s twist again
A jak tańczyć to przy muzyce. Dziś najprostszy odtwarzacz mp3 na stronę www. Oczywiście przy wykorzystaniu JavaFX Script.
Na początek ustalimy jedną rzecz. Wszystkie piosenki będą pobierane z XMLa:
Listing 1. Przykład XMLa z listą utworów
<?xml version="1.0" encoding="UTF-8"?>
<songs>
<song>
<url></url>
<title></title>
<artist></artist>
</song>
</songs>
Ważna rzecz numer 1. JavaFX słabo obsługuje polskie znaki w nazwach plików. Nie radzi sobie z tym po prostu. Założyłem już temat na forum i czekam na odpowiedź czy to jest bug. W każdym bądź razie naszego xmla mapujemy do klasy modelu:
Listing 2. Klasa Song
package pl.koziolekweb.fxmusicplayer;
import javafx.scene.media.Media;
/**
* @author koziolek
*/
public class Song {
public var url:String;
public var title:String;
public var artist:String;
public var media:Media;
public override function toString():String{
return "{artist}:{title} url:{url}";
}
}
Na razie wystarczy zabawy z modelem. Trzeba zająć się tworzeniem GUI dla naszego playera.
Przyciski itepe
Jako, że tworzymy najprostszą odmianę playera to wystarczy nam jeden przycisk. Będzie on odpowiadał za odtwarzanie i zatrzymywanie utworu. Do tego należy dodać tekst zawierający nazwę wykonawcy i tytuł piosenki i aktualny czas odtwarzania. Czyli nic trudnego.
Listing 3. GUI dumnie brzmi
var currentTime:Number = bind player.currentTime.toSeconds();
var maxTime:Number = bind player.media.duration.toSeconds();
var currentSongName: String = bind "{currentSongNumber}.{currentSong.artist}: {currentSong.title} {currentTime}:{maxTime}";
var contenGroup: Group= Group{
content: [
Text{
font: Font{
name:"Arial"
size: 10
}
x: 10
y: 10
content: bind currentSongName;
}
Polygon {
points: [ 20,20, 30,30, 20,40]
fill: Color.RED
onMouseClicked: function( e: MouseEvent ):Void {
if(status){
player.pause();
status= false;
}
else {
player.play();
status= true;
}
}
}
]
}
//...
Stage {
title: "Application title"
width: 300
height: 80
scene: Scene {
content: contenGroup
}
}
Co my tu mamy. Nasz przycisk stworzony za pomocą Polygon, bo chciałem wam pokazać, że takie coś istnieje. Zmienne currentSong,currentSongNumber i currentTime odpowiadają za przechowywanie aktualnej piosenki – Song, jej miejsca w playliście i aktualnego czasu odtwarzana. Zmienna maxTime określa czas trwania utworu w sekundach. Nie piszę tu kolejnego winampa więc olałem ładne formatowanie godzin, minut i sekund. Jest jeszcze magiczna zmienna player. O niej za chwilkę. Najpierw popatrzymy na pobieranie danych.
30… 30… 30 ton, czyli playlista
Playlista jest pobierana z serwera jako XML (ten na górze) i następnie przetwarzana:
Listing 4. Parser xml tworzy listę utworów
var parserHelper:Song;
def parser : PullParser = PullParser{
documentType: PullParser.XML
input: new FileInputStream(
new File("./music.xml"));
onEvent:function(event: Event) {
if (event.type == PullParser.START_ELEMENT) {
if(event.qname.name == "song" and event.level == 1) {
parserHelper = new Song();
}
}
if (event.type == PullParser.TEXT) {
if(event.qname.name == "url" and event.level == 2) {
if("{event.text.trim()}" != "")
parserHelper.url = event.text;
}
}
if (event.type == PullParser.TEXT) {
if(event.qname.name == "title" and event.level == 2) {
if("{event.text.trim()}" != "")
parserHelper.title = event.text;
}
}
if (event.type == PullParser.TEXT) {
if(event.qname.name == "artist" and event.level == 2) {
if("{event.text.trim()}" != "")
parserHelper.artist = event.text;
}
}
if (event.type == PullParser.END_ELEMENT) {
if(event.qname.name == "song" and event.level == 1) {
parserHelper.media = Media{
source: parserHelper.url
}
insert parserHelper into songs;
}
}
if (event.type == PullParser.END_DOCUMENT){
next();
}
}
};
parser.parse();
Ostatnia linijka spowoduje, że przy ładowaniu dokumentu rozpocznie się parsowanie co pozwoli na rozpoczęcie odtwarzania jak tylko będzie to możliwe najszybciej. Przy okazji zapoznamy się z funkcją next(), która „kieruje ruchem” w odtwarzaczu:
Listing 5. Funkcja next(), centrum kontroli
var trackListLength :Integer = bind songs.size();
var currentSongNumber: Integer = 0;
function next():Void{
player.stop();
currentSong = songs.get(currentSongNumber);
player.play();
status = true;
currentSongNumber++;
if(currentSongNumber == trackListLength){
currentSongNumber = 0;
}
}
Czas na wisienkę na naszym torcie…
Odtwarzacz
Mogło by się wydawać, że odtwarzanie utworu jest skomplikowane. Mam dla was złą wiadomość. W JavaFX Script sprowadza się to do kilku linijek kodu:
Listing 6. Zmienna player – super skomplikowany odtwarzacz
var status:Boolean = false;
var songs:Song[]=[];
var currentSong: Song;
def player : MediaPlayer = MediaPlayer{
media: bind currentSong.media;
autoPlay:true;
volume: 1.0;
onEndOfMedia: function():Void{
next();
}
}
Jedyną wadą obiektu MediaPlayer jest brak możliwości sprawdzenia stanu. Stąd zmienna status.
No i tyle. W kolejnym odcinku będziemy przerabiać nasz odtwarzacz na troszkę bardziej skomplikowany.