|
From: jreichen <jre...@us...> - 2011-01-15 21:09:55
|
Update of /cvsroot/sageplugins/MediaStreaming/src/sagex/streaming/httpls/playlist In directory sfp-cvsdas-3.v30.ch3.sourceforge.com:/tmp/cvs-serv18238/src/sagex/streaming/httpls/playlist Added Files: SegmentPlaylist.java VariantPlaylist.java Log Message: - Fixed problems watching shows currently being recorded - Refactored playlist generation code --- NEW FILE: VariantPlaylist.java --- package sagex.streaming.httpls.playlist; import java.util.UUID; import org.mortbay.log.Log; public class VariantPlaylist { public static String[] VARIANT_PLAYLIST_BITRATES = {"150", "1240", "840", "640", "440", "240"}; private int mediaFileId; private String playlist; public VariantPlaylist(int mediaFileId) { this.mediaFileId = mediaFileId; this.playlist = createPlaylist(); } private String createPlaylist() { StringBuilder sb = new StringBuilder(); String url = null; String conversionId = UUID.randomUUID().toString(); // Header sb.append("#EXTM3U\r\n"); Log.debug("#EXTM3U"); // Body for (String bitrate : VARIANT_PLAYLIST_BITRATES) { sb.append("#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=" + bitrate + "000\r\n"); Log.debug("#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=" + bitrate + "000"); url = "/stream/HTTPLiveStreamingPlaylist?" + "MediaFileId=" + mediaFileId + "&ConversionId=" + conversionId + "&Quality=" + bitrate; sb.append(url + "\r\n"); Log.debug(url); } return sb.toString(); } public String toString() { return this.playlist; } } --- NEW FILE: SegmentPlaylist.java --- package sagex.streaming.httpls.playlist; import java.util.ArrayList; import java.util.List; import org.mortbay.log.Log; import sagex.api.MediaFileAPI; public class SegmentPlaylist { public static final int TARGET_DURATION = 10; private Object mediaFile; private int mediaFileId; private List<Segment> segmentList; private String conversionId; private String quality; private boolean isFileCurrentlyRecording; public SegmentPlaylist(Object mediaFile, String conversionId, String quality) { this.mediaFile = mediaFile; this.mediaFileId = MediaFileAPI.GetMediaFileID(mediaFile); this.segmentList = new ArrayList<Segment>(); this.conversionId = conversionId; this.quality = quality; this.isFileCurrentlyRecording = MediaFileAPI.IsFileCurrentlyRecording(mediaFile); while (this.isFileCurrentlyRecording && segmentList.size() <= 1) { this.segmentList.clear(); createPlaylist(); long mediaFileSegmentDurationInMillis = MediaFileAPI.GetDurationForSegment(mediaFile, 0); long mediaFileSegmentDurationInSeconds = mediaFileSegmentDurationInMillis / 1000; // milliseconds to seconds if (this.isFileCurrentlyRecording && (mediaFileSegmentDurationInSeconds < SegmentPlaylist.TARGET_DURATION)) { try { // wait until we'll have a full first segment to return Thread.sleep((SegmentPlaylist.TARGET_DURATION - mediaFileSegmentDurationInSeconds + 1) * 1000); } catch (InterruptedException e) { Log.warn(e.getMessage()); } } this.isFileCurrentlyRecording = MediaFileAPI.IsFileCurrentlyRecording(mediaFile); } } private void createPlaylist() { String showName = MediaFileAPI.GetMediaTitle(mediaFile); int numberOfMediaFileSegments = MediaFileAPI.GetNumberOfSegments(mediaFile); for (int i = 0; i < numberOfMediaFileSegments; i++) { // get length of current media file segment long mediaFileSegmentDurationInMillis = MediaFileAPI.GetDurationForSegment(mediaFile, i); long mediaFileSegmentDurationInSeconds = mediaFileSegmentDurationInMillis / 1000; // milliseconds to seconds int sequence = 0; for (int j = 0; j < mediaFileSegmentDurationInSeconds; j += SegmentPlaylist.TARGET_DURATION) { long currentDuration = Math.min(SegmentPlaylist.TARGET_DURATION, mediaFileSegmentDurationInSeconds - j); Segment newSegment = new Segment(currentDuration, sequence, i, showName); segmentList.add(newSegment); sequence++; } } } public List<Segment> getSegments() { return segmentList; } public String toString() { StringBuilder sb = new StringBuilder(); String showName = MediaFileAPI.GetMediaTitle(mediaFile); int numberOfMediaFileSegments = MediaFileAPI.GetNumberOfSegments(mediaFile); Log.debug("Show: " + showName); Log.debug("MediaFileId: " + mediaFileId); Log.debug("Number Of MediaFile segments: " + numberOfMediaFileSegments); Log.debug("Is file currently recording: " + isFileCurrentlyRecording); sb.append("#EXTM3U\r\n"); Log.debug("#EXTM3U"); sb.append("#EXT-X-TARGETDURATION:" + TARGET_DURATION + "\r\n"); Log.debug("#EXT-X-TARGETDURATION:" + SegmentPlaylist.TARGET_DURATION); int segmentCount = (isFileCurrentlyRecording) ? segmentList.size() - 1 : segmentList.size(); for (int i = 0; i < segmentCount; i++) { String str = segmentList.get(i).toString(); sb.append(str); if ((i == 0) || (i >= segmentCount - 1)) { Log.debug(str); } } // #EXT-X-MEDIA-SEQUENCE:<number> // #EXT-X-PROGRAM-DATE-TIME:<YYYY-MM-DDThh:mm:ssZ> // #EXT-X-ALLOW-CACHE:<YES|NO> // #EXT-X-STREAM-INF if (!isFileCurrentlyRecording) { sb.append("#EXT-X-ENDLIST\r\n"); Log.debug("#EXT-X-ENDLIST"); } return sb.toString(); } public class Segment { private long segmentDuration; private int segmentSequence; private int mediaFileSegment; private String showName; public Segment(long segmentDuration, int segmentSequence, int mediaFileSegment, String showName) { this.segmentDuration = segmentDuration; this.segmentSequence = segmentSequence; this.mediaFileSegment = mediaFileSegment; this.showName = showName; } public String toString() { StringBuilder sb = new StringBuilder(); sb.append("#EXTINF:" + segmentDuration + "," + showName + "\r\n"); Log.debug("#EXTINF:" + segmentDuration + "," + showName); String url = "/stream/HTTPLiveStreamingSegment?" + "Sequence=" + segmentSequence + "&MediaFileId=" + mediaFileId + "&ConversionId=" + conversionId + "&Quality=" + quality + "&MediaFileSegment=" + mediaFileSegment; sb.append(url + "\r\n"); Log.debug(url); return sb.toString(); } } } |