Wednesday, July 4, 2007

Create customized repeat playlist in Red5

`Red5 server` is good alternative for FMS in some projects. For example you want to add audio streaming to your web site to play recorded MP3 files organized in playlists. This is like personal radio station. Good feature for such radio station is repeat playlists that play your songs one by one, and after last return to first.

Problem with Red5 default playlist implementation raise when you want to implement such thing. Unfortunately it never goes to second item of your list, it always play first item. Thanks to Red5 authors, they have added great feature to playlist implementation, this is `IPlaylistController` You just need your own controller implementation attached to playlist.

Controller source code:
import org.red5.server.api.stream.IPlaylist;
import org.red5.server.api.stream.IPlaylistController;

/**
* Playlist controller that cycle items in the
* following order: 1,2,3, 1,2,3, ...
*/
public class LongRepeatController implements IPlaylistController {
/** {@inheritDoc} */
public int nextItem(IPlaylist playlist, int itemIndex) {
return new ControllerImpl(playlist.getItemSize(), itemIndex).next();
}

/** {@inheritDoc} */
public int previousItem(IPlaylist playlist, int itemIndex) {
return new ControllerImpl(playlist.getItemSize(), itemIndex).previous();
}

/**
* Controller implementation subclass.
* Logic isolated here for easy testing.
*/
protected class ControllerImpl {
/** Total list size */
protected int size;

/** Current item index */
protected int current;

/**
* C-tor
*/
public ControllerImpl(int size, int current) {
this.size = size;
this.current = current;
}

/**
* @return Next play item
*/
public int next() {
if (current<0 || current>=size) {
return -1;
}
if (current==(size-1)) {
return 0;
} else {
return (current + 1);
}
}

/**
* @return Previous play item
*/
public int previous() {
if (current<0 || current>=size) {
return -1;
}
if (current==0) {
return (size-1);
} else {
return (current - 1);
}
}
}
}
Simple unit test for this simple class ;-)
import junit.framework.TestCase;

/**
* Test for long repeat playlist
*/
public class LongRepeatControllerTest extends TestCase {
/** Testing wrapper */
protected class LongRepeatControllerTester extends LongRepeatController {
public int next(int size, int cur) {
return new ControllerImpl(size, cur).next();
}

public int previous(int size, int cur) {
return new ControllerImpl(size, cur).previous();
}
}

/** Test for next */
public void testNext() {
LongRepeatControllerTester tester = new LongRepeatControllerTester();
assertEquals(-1, tester.next(5, -2));
assertEquals(1, tester.next(5, 0));
assertEquals(3, tester.next(5, 2));
assertEquals(0, tester.next(5, 4));
assertEquals(-1, tester.next(5, 6));
}

/** Test for previous */
public void testPrevious() {
LongRepeatControllerTester tester = new LongRepeatControllerTester();
assertEquals(-1, tester.previous(5, -2));
assertEquals(-1, tester.previous(5, 5));
assertEquals(2, tester.previous(5, 3));
assertEquals(0, tester.previous(5, 1));
assertEquals(4, tester.previous(5, 0));
}
}
Now just attach new controller to playlist (server stream) object:
serverStream.setRepeat(true);
serverStream.setPlaylistController(new LongRepeatController());
That's it!

0 comments: