Tuesday, July 17, 2007
The Development Process We Persistently Build
We have spent some time to draw the process we want to work with. And we do. Because the approach gives a good and reliable way to do the right things. Yes, we like lean development and we learn it every day. Everyday we think how to apply the lean principles to the Whirix company. Actually the only reason we do that is it makes our customers happy.
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:
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;Simple unit test for this simple class ;-)
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);
}
}
}
}
import junit.framework.TestCase;Now just attach new controller to playlist (server stream) object:
/**
* 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));
}
}
serverStream.setRepeat(true);That's it!
serverStream.setPlaylistController(new LongRepeatController());
Subscribe to:
Posts (Atom)