From: jreichen <jre...@us...> - 2011-01-15 21:13:38
|
Update of /cvsroot/sageplugins/MediaStreaming/src/sagex/streaming/servlet In directory sfp-cvsdas-3.v30.ch3.sourceforge.com:/tmp/cvs-serv19998/src/sagex/streaming/servlet Modified Files: HTTPLiveStreamingPlaylistServlet.java Log Message: - Added more logging detail - Refactored playlist generation code Index: HTTPLiveStreamingPlaylistServlet.java =================================================================== RCS file: /cvsroot/sageplugins/MediaStreaming/src/sagex/streaming/servlet/HTTPLiveStreamingPlaylistServlet.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** HTTPLiveStreamingPlaylistServlet.java 5 Nov 2010 02:58:36 -0000 1.2 --- HTTPLiveStreamingPlaylistServlet.java 15 Jan 2011 21:13:30 -0000 1.3 *************** *** 2,6 **** import java.util.Enumeration; - import java.util.UUID; import javax.servlet.http.HttpServletRequest; --- 2,5 ---- *************** *** 10,20 **** import sagex.api.MediaFileAPI; @SuppressWarnings("serial") public class HTTPLiveStreamingPlaylistServlet extends SageServlet { - public static final int TARGET_DURATION = 10; - private static String[] VARIANT_PLAYLIST_BITRATES = {"150", "1240", "840", "640", "440", "240"}; - public HTTPLiveStreamingPlaylistServlet() { --- 9,18 ---- import sagex.api.MediaFileAPI; + import sagex.streaming.httpls.playlist.SegmentPlaylist; + import sagex.streaming.httpls.playlist.VariantPlaylist; @SuppressWarnings("serial") public class HTTPLiveStreamingPlaylistServlet extends SageServlet { public HTTPLiveStreamingPlaylistServlet() { *************** *** 25,28 **** --- 23,31 ---- throws Exception { + // remove servlet URL from thread name so the SageTV log is easier to read + String threadName = Thread.currentThread().getName(); + int i = threadName.indexOf("/stream"); + Thread.currentThread().setName(threadName.substring(0, i)); + Object mediaFile = super.getMediaFile(req); if (mediaFile == null) *************** *** 30,33 **** --- 33,37 ---- throw new IllegalArgumentException("No MediaFileID passed"); } + int mediaFileId = MediaFileAPI.GetMediaFileID(mediaFile); Log.debug("----------- HTTPLiveStreamingPlaylistServlet begin request Headers ---------------"); *************** *** 44,47 **** --- 48,52 ---- Log.debug("----------- HTTPLiveStreamingPlaylistServlet end request Headers ---------------"); + // Servers that are constrained for compatibility can serve files ending in .m3u with MIME type audio/mpegURL // resp.setContentType("application/x-mpegURL"); resp.setContentType("application/vnd.apple.mpegurl"); *************** *** 50,62 **** String conversionId = req.getParameter("ConversionId"); String playlist = ""; if (conversionId == null) { ! playlist = createVariantPlaylist(req); } else { ! playlist = createSegmentPlaylist(req); } --- 55,68 ---- String conversionId = req.getParameter("ConversionId"); + String quality = req.getParameter("Quality"); String playlist = ""; if (conversionId == null) { ! playlist = new VariantPlaylist(mediaFileId).toString(); } else { ! playlist = new SegmentPlaylist(mediaFile, conversionId, quality).toString(); } *************** *** 84,222 **** catch (Exception e) { ! Log.info(e.getMessage()); ! Log.ignore(e); resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } finally { ! Log.debug("Chars: " + playlist.length() + ", Bytes: " + playlistBytes.length); ! } ! } ! ! private String createVariantPlaylist(HttpServletRequest req) ! { ! Object mediaFile = super.getMediaFile(req); ! if (mediaFile == null) ! { ! throw new IllegalArgumentException("No MediaFileID passed"); ! } ! int mediaFileId = MediaFileAPI.GetMediaFileID(mediaFile); ! ! StringBuilder sb = new StringBuilder(); ! ! String url = null; ! String conversionId = UUID.randomUUID().toString(); ! ! // Header ! sb.append("#EXTM3U\r\n"); ! Log.debug("#EXTM3U\r\n"); ! ! 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\r\n"); ! ! url = ("/stream/HTTPLiveStreamingPlaylist?" + ! "MediaFileId=" + mediaFileId + ! "&ConversionId=" + conversionId + ! "&Quality=" + bitrate + ! "\r\n"); ! sb.append(url); ! Log.debug(url); ! } ! ! return sb.toString(); ! ! // #EXTM3U ! // #EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=200000 ! // gear1/prog_index.m3u8 ! // #EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=311111 ! // gear2/prog_index.m3u8 ! // #EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=484444 ! // gear3/prog_index.m3u8 ! // #EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=737777 ! // gear4/prog_index.m3u8 ! ! } ! ! private String createSegmentPlaylist(HttpServletRequest req) ! { ! Object mediaFile = super.getMediaFile(req); ! if (mediaFile == null) ! { ! throw new IllegalArgumentException("No MediaFileID passed"); ! } ! ! String conversionId = req.getParameter("ConversionId"); ! String quality = req.getParameter("Quality"); ! ! String showName = MediaFileAPI.GetMediaTitle(mediaFile); ! int numberOfMediaFileSegments = MediaFileAPI.GetNumberOfSegments(mediaFile); ! boolean isRecording = MediaFileAPI.IsFileCurrentlyRecording(mediaFile); ! ! StringBuilder sb = new StringBuilder(); ! ! Log.debug("MediaFileId = " + req.getParameter("MediaFileId")); ! Log.debug("numberOfMediaFileSegments = " + numberOfMediaFileSegments); ! Log.debug("showName = " + showName); ! ! sb.append("#EXTM3U\r\n"); ! Log.debug("#EXTM3U\r\n"); ! ! sb.append("#EXT-X-TARGETDURATION:" + TARGET_DURATION + "\r\n"); ! Log.debug("#EXT-X-TARGETDURATION:" + TARGET_DURATION + "\r\n"); ! ! // sb.append("#EXT-X-MEDIA-SEQUENCE:0\r\n"); ! // Log.debug("#EXT-X-MEDIA-SEQUENCE:0\r\n"); ! ! for (int currentMediaFileSegment = 0; currentMediaFileSegment < numberOfMediaFileSegments; currentMediaFileSegment++) ! { ! // milliseconds ! long mediaFileSegmentDuration = MediaFileAPI.GetDurationForSegment(mediaFile, currentMediaFileSegment); ! Log.debug("segmentDuration = " + mediaFileSegmentDuration); ! mediaFileSegmentDuration = mediaFileSegmentDuration / 1000; // milliseconds to seconds ! int sequence = 0; // httpls segment sequence number ! for (int i = 0; i < mediaFileSegmentDuration; i += TARGET_DURATION) ! { ! long currentDuration = Math.min(TARGET_DURATION, mediaFileSegmentDuration - i); ! ! sb.append("#EXTINF:" + currentDuration + "," + showName + "\r\n"); ! Log.debug("#EXTINF:" + currentDuration + "," + showName + "\r\n"); ! ! // each segment has header and that causes problems with iphone ! ! // start frame hh:mm:ss:ff ! // hh:mm:ss:00 ! ! // duration hh:mm:ss:ff ! // 00:00:10:00 ! ! // sb.append("/sagem/m/TranscodedHTTPLiveStreamingMediaFile?s=" + i + "&d=" + currentDuration + "&MediaFileId=" + req.getParameter("MediaFileId") + "\r\n"); ! // System.out.print("/sagem/m/TranscodedHTTPLiveStreamingMediaFile?s=" + i + "&d=" + currentDuration + "&MediaFileId=" + req.getParameter("MediaFileId") + "\r\n"); ! String url = "/stream/HTTPLiveStreamingSegment?" + ! "Sequence=" + sequence + ! "&MediaFileId=" + req.getParameter("MediaFileId") + ! "&ConversionId=" + conversionId + ! "&Quality=" + quality + ! "&MediaFileSegment=" + currentMediaFileSegment + ! "\r\n"; ! sb.append(url); ! System.out.print(url); ! sequence++; ! } ! } ! ! // #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 (!isRecording) ! { ! sb.append("#EXT-X-ENDLIST\r\n"); ! Log.debug("#EXT-X-ENDLIST\r\n"); } - - return sb.toString(); } } --- 90,101 ---- catch (Exception e) { ! Log.warn(e.getMessage(), e); resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } finally { ! Log.debug("Playlist Chars: " + playlist.length() + ", Bytes: " + playlistBytes.length); ! Thread.currentThread().setName(threadName); } } } |