void gss_html_bootstrap_doc (GssTransaction * t) { GString *s = t->s; GSS_A ("<div class='hero-unit'>\n"); GSS_A ("<img src='/offline.png' alt='offline'>\n"); GSS_A ("<p>Content #1.</p>\n"); GSS_A ("<p><a class='btn btn-primary btn-large'>Learn more »</a></p>\n"); GSS_A ("</div>\n"); }
void gss_program_get_resource (GssTransaction * t) { GssProgram *program = (GssProgram *) t->resource->priv; GString *s = g_string_new (""); t->s = s; gss_html_header (t); GSS_P ("<h1>%s</h1>\n", GSS_OBJECT_SAFE_TITLE (program)); gss_program_add_video_block (program, t, 0); GSS_P ("<br>%s", program->safe_description); GSS_A ("<br>"); gss_program_add_stream_table (program, s); if (t->session && t->session->is_admin) { gss_config_append_config_block (G_OBJECT (program), t, FALSE); } gss_html_footer (t); }
void gss_transaction_error_not_found (GssTransaction * t, const char *reason) { char *content; t->debug_message = reason; if (t->server->enable_public_interface) { GString *s; t->s = g_string_new (""); s = t->s; gss_html_header (t); GSS_A ("<h1>Error 404: Not found</h1>\n"); gss_html_footer (t); content = g_string_free (s, FALSE); soup_message_set_response (t->msg, GSS_TEXT_HTML, SOUP_MEMORY_TAKE, content, strlen (content)); t->s = NULL; } else { content = g_strdup_printf ("404 Not found\n"); soup_message_set_response (t->msg, GSS_TEXT_PLAIN, SOUP_MEMORY_TAKE, content, strlen (content)); } soup_message_set_status (t->msg, SOUP_STATUS_NOT_FOUND); }
void gss_html_footer (GssTransaction * t) { GString *s = t->s; GSS_A ("</div><!--/span-->\n" "</div><!--/row-->\n"); if (t->server->footer_html) { t->server->footer_html (t->server, s, t->server->footer_html_priv); } else { GSS_A ("<div class='span4'>\n" "<p>© Entropy Wave Inc 2012</p>\n" "</div>\n"); } GSS_A ("</div><!--/.fluid-container-->\n"); GSS_A ("</body>\n"); gss_html_footer_bare (t); }
static void append_content_protection (GssTransaction * t, GssAdaptive * adaptive, const char *auth_token) { GString *s = t->s; if (adaptive->drm_type == GSS_DRM_PLAYREADY) { char *prot_header_base64; GSS_A (" <ContentProtection schemeIdUri=\"urn:mpeg:dash:" "mp4protection:2011\" value=\"cenc\"/>\n"); GSS_A (" <ContentProtection " "schemeIdUri=\"urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95\">\n"); prot_header_base64 = gss_playready_get_protection_header_base64 (adaptive, t->server->playready->license_url, auth_token); GSS_P (" <mspr:pro>%s</mspr:pro>\n", prot_header_base64); g_free (prot_header_base64); GSS_A (" </ContentProtection>\n"); } }
void gss_html_append_image (GString * s, const char *url, int width, int height, const char *alt_text) { if (alt_text == NULL) alt_text = ""; GSS_P ("<img src='%s' alt='%s' ", url, alt_text ? alt_text : ""); if (width > 0 && height > 0) { GSS_P ("width='%d' height='%d' ", width, height); } GSS_A ("/>"); }
void gss_html_footer_bare (GssTransaction * t) { GString *s = t->s; char *base_https; GSS_A ("<script src='/bootstrap/js/jquery.js'></script>\n"); GSS_A ("<script src='/bootstrap/js/bootstrap.js'></script>\n"); #ifdef use_internal_include_js GSS_A ("<script src=\"/include.js\" type=\"text/javascript\"></script>\n"); #else GSS_A ("<script src=\"https://login.persona.org/include.js\" type=\"text/javascript\"></script>\n"); #endif if (t->server->enable_flowplayer) { GSS_A ("<script type='text/javascript' src=\"/flowplayer-3.2.11.min.js\"></script>\n" "<script>flowplayer('player', '/flowplayer-3.2.15.swf');</script>\n"); } GSS_A ("<script type=\"text/javascript\">\n"); base_https = gss_soup_get_base_url_https (t->server, t->msg); GSS_P ("function gotAssertion(assertion) {\n" "if(assertion!==null){\n" "var form = document.createElement(\"form\");\n" "form.setAttribute('method', 'POST');\n" "form.setAttribute('action', '%s/login?redirect_url=%s');\n" "var ip = document.createElement(\"input\");\n" "ip.setAttribute('type', 'hidden');\n" "ip.setAttribute('name', 'assertion');\n" "ip.setAttribute('value', assertion);\n" "form.appendChild(ip);\n" "document.body.appendChild(form);\n" "form.submit();\n" "}\n" "}\n", base_https, t->path ? t->path : "/"); g_free (base_https); if (t->script) { GSS_A (t->script->str); g_string_free (t->script, TRUE); } GSS_A ("</script>\n"); GSS_A ("\n" "</body>\n" "</html>\n"); }
void gss_html_header_bare (GssTransaction * t) { GString *s = t->s; GSS_P ("<!DOCTYPE html>\n" "<html lang='en'>\n" "<head>\n" "<meta charset='utf-8'>\n" "<title>%s</title>\n", GSS_OBJECT_SAFE_TITLE (t->server)); GSS_A ("<meta name='viewport' content='width=device-width, initial-scale=1.0'>\n"); #if 0 GSS_A ("<meta name='description' content=''>\n" "<meta name='author' content=''>\n"); #endif GSS_A ("<link href='/bootstrap/css/bootstrap.css' rel='stylesheet'>\n"); GSS_A ("<style type='text/css'>\n" "body {\n" "padding-top: 60px;\n" "padding-bottom: 40px;\n" "}\n" ".sidebar-nav {\n" "padding: 9px 0;\n" "}\n" "</style>\n"); GSS_A ("<link href='/bootstrap/css/bootstrap-responsive.css' rel='stylesheet'>\n"); #if 0 GSS_A ("<!--[if lt IE 9]>\n" "<script src='http://html5shim.googlecode.com/svn/trunk/html5.js'></script>\n" "<![endif]-->\n"); #endif #if 0 GSS_A ("<link rel='shortcut icon' href='/favicon.ico'>\n"); GSS_A ("<link rel='apple-touch-icon-precomposed' sizes='144x144' href='../assets/ico/apple-touch-icon-144-precomposed.png'>\n" "<link rel='apple-touch-icon-precomposed' sizes='114x114' href='../assets/ico/apple-touch-icon-114-precomposed.png'>\n" "<link rel='apple-touch-icon-precomposed' sizes='72x72' href='../assets/ico/apple-touch-icon-72-precomposed.png'>\n" "<link rel='apple-touch-icon-precomposed' href='../assets/ico/apple-touch-icon-57-precomposed.png'>\n"); #endif GSS_A ("</head>\n"); }
void gss_html_error_404 (GssServer * server, SoupMessage * msg) { char *content; GString *s; GssTransaction t = { 0 }; s = g_string_new (""); t.s = s; t.server = server; t.msg = msg; gss_html_header (&t); GSS_A ("<h1>Error 404: Page not found</h1>\n"); gss_html_footer (&t); content = g_string_free (s, FALSE); soup_message_set_response (msg, GSS_TEXT_HTML, SOUP_MEMORY_TAKE, content, strlen (content)); soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND); }
static void gss_server_resource_about (GssTransaction * t) { GString *s; s = t->s = g_string_new (""); gss_html_header (t); GSS_P ("<h2>About</h2>\n"); GSS_P ("<p>GStreamer Streaming Server is based on the work of many\n"); GSS_P ("open source projects, some of which are listed below.\n"); GSS_P ("</p>\n"); GSS_P ("<h3>GStreamer Streaming Server</h3>\n"); GSS_P ("<pre>\n"); GSS_P ("Copyright (C) 2009-2012 Entropy Wave Inc <[email protected]>\n"); GSS_P ("Copyright (C) 2009-2012 David Schleef <[email protected]>\n"); GSS_P ("Copyright (C) 2012 Jan Schmidt <[email protected]>\n"); GSS_P ("Copyright (C) 2013 Rdio Inc <[email protected]>\n"); GSS_P ("\n"); GSS_P ("This library is free software; you can redistribute it and/or\n"); GSS_P ("modify it under the terms of the GNU Library General Public\n"); GSS_P ("License as published by the Free Software Foundation; either\n"); GSS_P ("version 2 of the License, or (at your option) any later version.\n"); GSS_P ("\n"); GSS_P ("This library is distributed in the hope that it will be useful,\n"); GSS_P ("but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); GSS_P ("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"); GSS_P ("Library General Public License for more details.\n"); GSS_P ("\n"); GSS_P ("You should have received a copy of the GNU Library General Public\n"); GSS_P ("License along with this library; if not, write to the\n"); GSS_P ("Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,\n"); GSS_P ("Boston, MA 02110-1301, USA.\n"); GSS_P ("</pre>\n"); GSS_P ("<h3>Twitter Bootstrap</h3>\n"); GSS_P ("<pre>\n"); GSS_A ("Copyright 2012 Twitter, Inc\n"); GSS_A ("Licensed under the Apache License v2.0\n"); GSS_A ("http://www.apache.org/licenses/LICENSE-2.0\n"); GSS_A ("\n"); GSS_A ("Designed and built with all the love in the world @twitter by @mdo and @fat.\n"); GSS_P ("</pre>\n"); GSS_P ("<h3>GStreamer</h3>\n"); GSS_P ("<p>Includes gstreamer, gst-plugins-base, gst-plugins-good, \n"); GSS_P ("gst-plugins-bad, and gst-rtsp-server.</p>\n"); GSS_P ("<pre>\n"); GSS_P ("Copyright (C) 1999-2012 GStreamer contributors\n"); GSS_P ("\n"); GSS_P ("This library is free software; you can redistribute it and/or\n"); GSS_P ("modify it under the terms of the GNU Library General Public\n"); GSS_P ("License as published by the Free Software Foundation; either\n"); GSS_P ("version 2 of the License, or (at your option) any later version.\n"); GSS_P ("\n"); GSS_P ("This library is distributed in the hope that it will be useful,\n"); GSS_P ("but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); GSS_P ("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"); GSS_P ("Library General Public License for more details.\n"); GSS_P ("\n"); GSS_P ("You should have received a copy of the GNU Library General Public\n"); GSS_P ("License along with this library; if not, write to the\n"); GSS_P ("Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,\n"); GSS_P ("Boston, MA 02110-1301, USA.\n"); GSS_P ("</pre>\n"); GSS_P ("<h3>Libsoup</h3>\n"); GSS_P ("<pre>\n"); GSS_P ("Copyright (C) 2009, 2010 Red Hat, Inc.\n"); GSS_A ("Copyright 1999-2003 Ximian, Inc.\n"); GSS_A ("Copyright (C) 2000-2003, Ximian, Inc.\n"); GSS_A ("Copyright (C) 2001-2007 Novell, Inc.\n"); GSS_A ("Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc.\n"); GSS_A ("Copyright (C) 2008 Diego Escalante Urrelo\n"); GSS_A ("Copyright (C) 2009, 2011 Collabora Ltd.\n"); GSS_A ("Copyright (C) 2009 Gustavo Noronha Silva.\n"); GSS_A ("Copyright (C) 2009, 2010 Igalia S.L.\n"); GSS_P ("\n"); GSS_P ("This library is free software; you can redistribute it and/or\n"); GSS_P ("modify it under the terms of the GNU Library General Public\n"); GSS_P ("License as published by the Free Software Foundation; either\n"); GSS_P ("version 2 of the License, or (at your option) any later version.\n"); GSS_P ("\n"); GSS_P ("This library is distributed in the hope that it will be useful,\n"); GSS_P ("but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); GSS_P ("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"); GSS_P ("Library General Public License for more details.\n"); GSS_P ("\n"); GSS_P ("You should have received a copy of the GNU Library General Public\n"); GSS_P ("License along with this library; if not, write to the\n"); GSS_P ("Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,\n"); GSS_P ("Boston, MA 02110-1301, USA.\n"); GSS_P ("</pre>\n"); GSS_P ("<h3>JSON-Glib</h3>\n"); GSS_P ("<pre>\n"); GSS_P ("Copyright (C) 1997, 1998 Tim Janik\n"); GSS_P ("Copyright (C) 2007, 2008, 2009 OpenedHand Ltd.\n"); GSS_P ("Copyright (C) 2009, 2010, 2011 Intel Corp.\n"); GSS_P ("Copyright (C) 2010 Luca Bruno <[email protected]>\n"); GSS_P ("\n"); GSS_P ("This library is free software; you can redistribute it and/or\n"); GSS_P ("modify it under the terms of the GNU Lesser General Public\n"); GSS_P ("License as published by the Free Software Foundation; either\n"); GSS_P ("version 2.1 of the License, or (at your option) any later version.\n"); GSS_P ("\n"); GSS_P ("This library is distributed in the hope that it will be useful,\n"); GSS_P ("but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); GSS_P ("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"); GSS_P ("Library General Public License for more details.\n"); GSS_P ("\n"); GSS_P ("You should have received a copy of the GNU Library General Public\n"); GSS_P ("License along with this library; if not, write to the\n"); GSS_P ("Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,\n"); GSS_P ("Boston, MA 02110-1301, USA.\n"); GSS_P ("</pre>\n"); GSS_P ("<h3>dashif.org DASH player</h3>\n"); GSS_P ("<pre>\n"); GSS_P ("The copyright in this software is being made available under\n"); GSS_P ("the BSD License,\n"); GSS_P ("included below. This software may be subject to other third\n"); GSS_P ("party and contributor rights, including patent rights, and no\n"); GSS_P ("such rights are granted under this license.\n"); GSS_P ("\n"); GSS_P ("Copyright (c) 2013, Digital Primates\n"); GSS_P ("All rights reserved.\n"); GSS_P ("\n"); GSS_P ("Redistribution and use in source and binary forms, with or\n"); GSS_P ("without modification, are permitted provided that the following\n"); GSS_P ("conditions are met:\n"); GSS_P ("Redistributions of source code must retain the above copyright\n"); GSS_P ("notice, this list of conditions and the following disclaimer.\n"); GSS_P ("Redistributions in binary form must reproduce the above copyright\n"); GSS_P ("notice, this list of conditions and the following disclaimer in\n"); GSS_P ("the documentation and/or other materials provided with the\n"); GSS_P ("distribution.\n"); GSS_P ("Neither the name of the Digital Primates nor the names of its\n"); GSS_P ("contributors may be used to endorse or promote products derived\n"); GSS_P ("from this software without specific prior written permission.\n"); GSS_P ("\n"); GSS_P ("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n"); GSS_P ("CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n"); GSS_P ("INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n"); GSS_P ("MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n"); GSS_P ("DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR\n"); GSS_P ("CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"); GSS_P ("SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"); GSS_P ("LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF\n"); GSS_P ("USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n"); GSS_P ("AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n"); GSS_P ("LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\n"); GSS_P ("IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n"); GSS_P ("THE POSSIBILITY OF SUCH DAMAGE.\n"); GSS_P ("\n"); GSS_P ("</pre>\n"); gss_html_footer (t); }
static void gss_adaptive_resource_get_dash_live_mpd (GssTransaction * t, GssAdaptive * adaptive) { GString *s = g_string_new (""); int i; ManifestQuery mq; parse_manifest_query (&mq, t); t->s = s; soup_message_headers_replace (t->msg->response_headers, "Content-Type", "application/octet-stream"); GSS_P ("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); GSS_A ("<MPD xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" " xmlns=\"urn:mpeg:dash:schema:mpd:2011\"\n"); if (adaptive->drm_type == GSS_DRM_PLAYREADY) { GSS_A (" xmlns:mspr=\"urn:microsoft:playready\"\n"); } GSS_P (" xsi:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\"\n" " type=\"static\"\n" " mediaPresentationDuration=\"PT%dS\"\n" " minBufferTime=\"PT10S\"\n" " profiles=\"urn:mpeg:dash:profile:isoff-live:2011\">\n", (int) (adaptive->duration / GSS_ISM_SECOND)); GSS_P (" <Period>\n"); GSS_A (" <AdaptationSet " "id=\"1\" " "profiles=\"ccff\" " "bitstreamSwitching=\"true\" " "segmentAlignment=\"true\" " "contentType=\"audio\" " "mimeType=\"audio/mp4\" " "lang=\"en\">\n"); append_content_protection (t, adaptive, mq.auth_token); GSS_A (" <SegmentTemplate timescale=\"10000000\" " "media=\"content?stream=audio&bitrate=$Bandwidth$&start_time=$Time$\" " "initialization=\"content?stream=audio&bitrate=$Bandwidth$&start_time=init\">\n"); GSS_A (" <SegmentTimeline>\n"); { GssAdaptiveLevel *level = &adaptive->audio_levels[0]; for (i = 0; i < level->n_fragments; i++) { GssIsomFragment *fragment; fragment = gss_isom_track_get_fragment (level->track, i); GSS_P (" <S d=\"%" G_GUINT64_FORMAT "\" />\n", (guint64) fragment->duration); } } GSS_A (" </SegmentTimeline>\n"); GSS_A (" </SegmentTemplate>\n"); for (i = 0; i < adaptive->n_audio_levels; i++) { GssAdaptiveLevel *level = &adaptive->audio_levels[i]; GSS_P (" <Representation id=\"a%d\" codecs=\"%s\" " "bandwidth=\"%d\" audioSamplingRate=\"%d\"/>\n", i, level->codec, level->bitrate, level->audio_rate); } GSS_A (" </AdaptationSet>\n"); GSS_P (" <AdaptationSet " "id=\"2\" " "profiles=\"ccff\" " "bitstreamSwitching=\"true\" " "segmentAlignment=\"true\" " "contentType=\"video\" " "mimeType=\"video/mp4\" " "maxWidth=\"1920\" " "maxHeight=\"1080\" " "startWithSAP=\"1\">\n"); append_content_protection (t, adaptive, mq.auth_token); GSS_A (" <SegmentTemplate timescale=\"10000000\" " "media=\"content?stream=video&bitrate=$Bandwidth$&start_time=$Time$\" " "initialization=\"content?stream=video&bitrate=$Bandwidth$&start_time=init\">\n"); GSS_A (" <SegmentTimeline>\n"); { GssAdaptiveLevel *level = &adaptive->video_levels[0]; for (i = 0; i < level->n_fragments; i++) { GssIsomFragment *fragment; fragment = gss_isom_track_get_fragment (level->track, i); GSS_P (" <S d=\"%" G_GUINT64_FORMAT "\" />\n", (guint64) fragment->duration); } } GSS_A (" </SegmentTimeline>\n"); GSS_A (" </SegmentTemplate>\n"); for (i = 0; i < adaptive->n_video_levels; i++) { GssAdaptiveLevel *level = &adaptive->video_levels[i]; if (manifest_query_check_video (&mq, level)) { GSS_P (" <Representation id=\"v%d\" bandwidth=\"%d\" " "codecs=\"%s\" width=\"%d\" height=\"%d\"/>\n", i, level->bitrate, level->codec, level->video_width, level->video_height); } } GSS_A (" </AdaptationSet>\n"); GSS_A (" </Period>\n"); GSS_A ("</MPD>\n"); GSS_A ("\n"); }
static void gss_adaptive_resource_get_dash_range_mpd (GssTransaction * t, GssAdaptive * adaptive) { GString *s = g_string_new (""); int i; ManifestQuery mq; parse_manifest_query (&mq, t); t->s = s; soup_message_headers_replace (t->msg->response_headers, "Content-Type", "application/octet-stream"); GSS_A ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); GSS_A ("<MPD xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" " xmlns=\"urn:mpeg:dash:schema:mpd:2011\"\n"); if (adaptive->drm_type == GSS_DRM_PLAYREADY) { GSS_A (" xmlns:mspr=\"urn:microsoft:playready\"\n"); } GSS_P (" xsi:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\"\n" " type=\"static\"\n" " mediaPresentationDuration=\"PT%dS\"\n" " minBufferTime=\"PT10S\"\n" " profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\">\n", (int) (adaptive->duration / GSS_ISM_SECOND)); GSS_P (" <Period>\n"); GSS_A (" <AdaptationSet mimeType=\"audio/mp4\" " "lang=\"en\" " "segmentAlignment=\"true\" " "subsegmentAlignment=\"true\" " "subsegmentStartsWithSAP=\"1\">\n"); append_content_protection (t, adaptive, mq.auth_token); for (i = 0; i < adaptive->n_audio_levels; i++) { GssAdaptiveLevel *level = &adaptive->audio_levels[i]; GssIsomTrack *track = level->track; GSS_P (" <Representation id=\"a%d\" codecs=\"%s\" bandwidth=\"%d\">\n", i, level->codec, level->bitrate); GSS_P (" <BaseURL>content/a%d</BaseURL>\n", i); GSS_P (" <SegmentBase indexRange=\"%" G_GSIZE_FORMAT "-%" G_GSIZE_FORMAT "\">" "<Initialization range=\"%" G_GSIZE_FORMAT "-%" G_GSIZE_FORMAT "\" /></SegmentBase>\n", track->dash_header_size, track->dash_header_and_sidx_size - 1, (gsize) 0, track->dash_header_size - 1); GSS_A (" </Representation>\n"); break; } GSS_A (" </AdaptationSet>\n"); GSS_A (" <AdaptationSet mimeType=\"video/mp4\" " "segmentAlignment=\"true\" " "subsegmentAlignment=\"true\" " "subsegmentStartsWithSAP=\"1\">\n"); append_content_protection (t, adaptive, mq.auth_token); for (i = 0; i < adaptive->n_video_levels; i++) { GssAdaptiveLevel *level = &adaptive->video_levels[i]; GssIsomTrack *track = level->track; if (manifest_query_check_video (&mq, level)) { GSS_P (" <Representation id=\"v%d\" bandwidth=\"%d\" " "codecs=\"%s\" width=\"%d\" height=\"%d\">\n", i, level->bitrate, level->codec, level->video_width, level->video_height); GSS_P (" <BaseURL>content/v%d</BaseURL>\n", i); GSS_P (" <SegmentBase indexRange=\"%" G_GSIZE_FORMAT "-%" G_GSIZE_FORMAT "\">" "<Initialization range=\"%" G_GSIZE_FORMAT "-%" G_GSIZE_FORMAT "\" /></SegmentBase>\n", track->dash_header_size, track->dash_header_and_sidx_size - 1, (gsize) 0, track->dash_header_size - 1); GSS_A (" </Representation>\n"); } } GSS_A (" </AdaptationSet>\n"); GSS_A (" </Period>\n"); GSS_A ("</MPD>\n"); GSS_A ("\n"); }
static void gss_adaptive_resource_get_manifest (GssTransaction * t, GssAdaptive * adaptive) { GString *s = g_string_new (""); ManifestQuery mq; int i; int show_audio_levels; t->s = s; parse_manifest_query (&mq, t); GSS_A ("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); GSS_P ("<SmoothStreamingMedia MajorVersion=\"2\" MinorVersion=\"1\" Duration=\"%" G_GUINT64_FORMAT "\">\n", adaptive->duration); GSS_P (" <StreamIndex Type=\"video\" Name=\"video\" Chunks=\"%d\" QualityLevels=\"%d\" MaxWidth=\"%d\" MaxHeight=\"%d\" " "DisplayWidth=\"%d\" DisplayHeight=\"%d\" " "Url=\"content?stream=video&bitrate={bitrate}&start_time={start time}\">\n", adaptive->video_levels[0].n_fragments, adaptive->n_video_levels, adaptive->max_width, adaptive->max_height, adaptive->max_width, adaptive->max_height); /* also IsLive, LookaheadCount, DVRWindowLength */ for (i = 0; i < adaptive->n_video_levels; i++) { GssAdaptiveLevel *level = &adaptive->video_levels[i]; if (manifest_query_check_video (&mq, level)) { GSS_P (" <QualityLevel Index=\"%d\" Bitrate=\"%d\" " "FourCC=\"H264\" MaxWidth=\"%d\" MaxHeight=\"%d\" " "CodecPrivateData=\"%s\" />\n", i, level->bitrate, level->video_width, level->video_height, level->codec_data); } } { GssAdaptiveLevel *level = &adaptive->video_levels[0]; for (i = 0; i < level->n_fragments; i++) { GssIsomFragment *fragment; fragment = gss_isom_track_get_fragment (level->track, i); GSS_P (" <c d=\"%" G_GUINT64_FORMAT "\" />\n", (guint64) fragment->duration); } } GSS_A (" </StreamIndex>\n"); show_audio_levels = 1; GSS_P (" <StreamIndex Type=\"audio\" Index=\"0\" Name=\"audio\" " "Chunks=\"%d\" QualityLevels=\"%d\" " "Url=\"content?stream=audio&bitrate={bitrate}&start_time={start time}\">\n", adaptive->audio_levels[0].n_fragments, show_audio_levels); for (i = 0; i < show_audio_levels; i++) { GssAdaptiveLevel *level = &adaptive->audio_levels[i]; GSS_P (" <QualityLevel FourCC=\"AACL\" Bitrate=\"%d\" " "SamplingRate=\"%d\" Channels=\"2\" BitsPerSample=\"16\" " "PacketSize=\"4\" AudioTag=\"255\" CodecPrivateData=\"%s\" />\n", level->bitrate, level->audio_rate, level->codec_data); break; } { GssAdaptiveLevel *level = &adaptive->audio_levels[0]; for (i = 0; i < level->n_fragments; i++) { GssIsomFragment *fragment; fragment = gss_isom_track_get_fragment (level->track, i); GSS_P (" <c d=\"%" G_GUINT64_FORMAT "\" />\n", (guint64) fragment->duration); } } GSS_A (" </StreamIndex>\n"); if (adaptive->drm_type == GSS_DRM_PLAYREADY) { char *prot_header_base64; GSS_A ("<Protection>\n"); GSS_A (" <ProtectionHeader " "SystemID=\"9a04f079-9840-4286-ab92-e65be0885f95\">"); prot_header_base64 = gss_playready_get_protection_header_base64 (adaptive, t->server->playready->license_url, mq.auth_token); GSS_P ("%s", prot_header_base64); g_free (prot_header_base64); GSS_A ("</ProtectionHeader>\n"); GSS_A ("</Protection>\n"); } GSS_A ("</SmoothStreamingMedia>\n"); }
void gss_program_add_stream_table (GssProgram * program, GString * s) { GList *g; gboolean have_hls = FALSE; GSS_A ("<table class='table table-striped table-bordered " "table-condensed'>\n"); GSS_A ("<thead>\n"); GSS_A ("<tr>\n"); GSS_A ("<th>Type</th>\n"); GSS_A ("<th>Size</th>\n"); GSS_A ("<th>Bitrate</th>\n"); GSS_A ("</tr>\n"); GSS_A ("</thead>\n"); GSS_A ("<tbody>\n"); for (g = program->streams; g; g = g_list_next (g)) { GssStream *stream = g->data; GSS_A ("<tr>\n"); GSS_P ("<td>%s</td>\n", gss_stream_type_get_name (stream->type)); GSS_P ("<td>%dx%d</td>\n", stream->width, stream->height); GSS_P ("<td>%d kbps</td>\n", stream->bitrate / 1000); GSS_P ("<td><a href=\"%s\">stream</a></td>\n", stream->location); GSS_P ("<td><a href=\"%s\">playlist</a></td>\n", stream->playlist_location); GSS_A ("</tr>\n"); if (stream->type == GSS_STREAM_TYPE_M2TS_H264BASE_AAC || stream->type == GSS_STREAM_TYPE_M2TS_H264MAIN_AAC) { have_hls = TRUE; } } if (have_hls) { GSS_A ("<tr>\n"); GSS_P ("<td colspan='7'><a href='/%s.m3u8'>HLS</a></td>\n", GST_OBJECT_NAME (program)); GSS_A ("</tr>\n"); } GSS_A ("<tr>\n"); GSS_P ("<td colspan='7'><a class='btn btn-mini' href='/'>" "<i class='icon-plus'></i>Add</a></td>\n"); GSS_A ("</tr>\n"); GSS_A ("</tbody>\n"); GSS_A ("</table>\n"); }
void gss_program_add_video_block (GssProgram * program, GssTransaction * t, int max_width) { GString *s = t->s; GList *g; int width = 0; int height = 0; int flash_only = TRUE; if (program->state != GSS_PROGRAM_STATE_RUNNING) { GSS_P ("<img src='/offline.png'>\n"); return; } if (program->streams == NULL) { if (program->jpegsink) { gss_html_append_image_printf (s, "/%s-snapshot.jpeg", 0, 0, "snapshot image", GST_OBJECT_NAME (program)); } else { GSS_P ("<img src='/no-snapshot.png'>\n"); } } for (g = program->streams; g; g = g_list_next (g)) { GssStream *stream = g->data; if (stream->width > width) width = stream->width; if (stream->height > height) height = stream->height; if (stream->type != GSS_STREAM_TYPE_FLV_H264BASE_AAC) { flash_only = FALSE; } } if (max_width != 0 && width > max_width) { height = max_width * 9 / 16; width = max_width; } if (program->server->enable_html5_video && !flash_only) { GSS_P ("<video controls=\"controls\" autoplay=\"autoplay\" " "id=video width=\"%d\" height=\"%d\">\n", width, height); for (g = g_list_last (program->streams); g; g = g_list_previous (g)) { GssStream *stream = g->data; if (stream->type == GSS_STREAM_TYPE_WEBM) { GSS_P ("<source src=\"%s\" type='video/webm; codecs=\"vp8, vorbis\"'>\n", stream->location); } } for (g = g_list_last (program->streams); g; g = g_list_previous (g)) { GssStream *stream = g->data; if (stream->type == GSS_STREAM_TYPE_OGG_THEORA_VORBIS) { GSS_P ("<source src=\"%s\" type='video/ogg; codecs=\"theora, vorbis\"'>\n", stream->location); } } for (g = g_list_last (program->streams); g; g = g_list_previous (g)) { GssStream *stream = g->data; if (stream->type == GSS_STREAM_TYPE_M2TS_H264BASE_AAC || stream->type == GSS_STREAM_TYPE_M2TS_H264MAIN_AAC) { GSS_P ("<source src=\"/%s.m3u8\" >\n", GST_OBJECT_NAME (program)); break; } } } if (program->server->enable_cortado) { for (g = program->streams; g; g = g_list_next (g)) { GssStream *stream = g->data; if (stream->type == GSS_STREAM_TYPE_OGG_THEORA_VORBIS) { GSS_P ("<applet code=\"com.fluendo.player.Cortado.class\"\n" " archive=\"/cortado.jar\" width=\"%d\" height=\"%d\">\n" " <param name=\"url\" value=\"%s\"></param>\n" "</applet>\n", width, height, stream->location); break; } } } if (program->server->enable_flash) { for (g = program->streams; g; g = g_list_next (g)) { GssStream *stream = g->data; if (stream->type == GSS_STREAM_TYPE_FLV_H264BASE_AAC) { if (t->server->enable_osplayer) { GSS_P (" <object width='%d' height='%d' id='flvPlayer' " "type=\"application/x-shockwave-flash\" " "data=\"OSplayer.swf\">\n" " <param name='allowFullScreen' value='true'>\n" " <param name=\"allowScriptAccess\" value=\"always\"> \n" " <param name=\"movie\" value=\"OSplayer.swf\"> \n" " <param name=\"flashvars\" value=\"" "movie=%s" "&btncolor=0x333333" "&accentcolor=0x31b8e9" "&txtcolor=0xdddddd" "&volume=30" "&autoload=on" "&autoplay=off" "&vTitle=TITLE" "&showTitle=yes\">\n", width, height + 24, stream->location); if (program->enable_snapshot) { gss_html_append_image_printf (s, "/%s-snapshot.png", 0, 0, "snapshot image", GST_OBJECT_NAME (program)); } GSS_P (" </object>\n"); } else if (t->server->enable_flowplayer) { GSS_P ("<a href='%s' style='display:block;width:%dpx;height:%dpx' id='player'>_</a>\n", stream->location, width, height); } break; } } } else { if (program->enable_snapshot) { gss_html_append_image_printf (s, "/%s-snapshot.png", 0, 0, "snapshot image", GST_OBJECT_NAME (program)); } } if (program->server->enable_html5_video && !flash_only) { GSS_A ("</video>\n"); } }
void gss_html_header (GssTransaction * t) { GString *s = t->s; gchar *session_id; GList *g; if (t->session) { session_id = g_strdup_printf ("?session_id=%s", t->session->session_id); } else { session_id = g_strdup (""); } gss_html_header_bare (t); GSS_A ("<body>\n"); GSS_A ("<div class='navbar navbar-fixed-top'>\n" "<div class='navbar-inner'>\n" "<div class='container-fluid'>\n" "<a class='btn btn-navbar' data-toggle='collapse' data-target='.nav-collapse'>\n" "<span class='icon-bar'></span>\n" "<span class='icon-bar'></span>\n" "<span class='icon-bar'></span>\n" "</a>\n"); GSS_P ("<a class='brand' href='/%s'>%s</a>\n" "<div class='btn-group pull-right'>\n", session_id, GSS_OBJECT_SAFE_TITLE (t->server)); if (t->session) { GSS_P ("<a class='btn dropdown-toggle' data-toggle='dropdown' data-target='#'>\n" "<i class='icon-user'></i> %s\n" "<span class='caret'></span></a>\n", t->session->username); } else { t->server->append_login_html (t->server, t); } GSS_P ("<ul class='dropdown-menu'>\n" "<li><a href='/profile%s'>Profile</a></li>\n" "<li class='divider'></li>\n" "<li><a href='/logout%s'>Sign Out</a></li>\n" "</ul>\n" "</div>\n" "<div class='nav-collapse'>\n" "<ul class='nav'>\n" "<li class='active'><a href='/%s'>Home</a></li>\n" "<li><a href='/about%s'>About</a></li>\n" "<li><a href='/contact%s'>Contact</a></li>\n" "</ul>\n" "</div><!--/.nav-collapse -->\n" "</div>\n" "</div>\n" "</div>\n" "<div class='container-fluid'>\n" "<div class='row-fluid'>\n" "<div class='span3'>\n" "<div class='well sidebar-nav'>\n", session_id, session_id, session_id, session_id, session_id); GSS_A ("<ul class='nav nav-list'>\n"); if (t->server->featured_resources) { GSS_A ("<li class='nav-header'>Featured Pages</li>\n"); for (g = t->server->featured_resources; g; g = g_list_next (g)) { GssResource *resource = g->data; GSS_P ("<li %s><a href='%s%s'>%s</a></li>\n", (resource == t->resource) ? "class='active'" : "", resource->location, session_id, resource->name); }; } GSS_A ("<li class='nav-header'>Programs</li>\n"); for (g = t->server->programs; g; g = g_list_next (g)) { GssProgram *program = g->data; if (program->is_archive) continue; GSS_P ("<li %s><a href='%s%s'>%s</a></li>\n", (program->resource == t->resource) ? "class='active'" : "", program->resource->location, session_id, GSS_OBJECT_SAFE_TITLE (program)); }; if (t->server->enable_vod) { GSS_A ("<li class='nav-header'>Archive</li>\n"); for (g = t->server->programs; g; g = g_list_next (g)) { GssProgram *program = g->data; if (!program->is_archive) continue; GSS_P ("<li %s><a href='%s%s'>%s</a></li>\n", (program->resource == t->resource) ? "class='active'" : "", program->resource->location, session_id, GSS_OBJECT_SAFE_TITLE (program)); }; if (t->session) { GSS_P ("<li class='nav-header'>User</li>\n" "<li><a href='/add_program%s'>Add Program</a></li>\n" "<li><a href='/dashboard%s'>Dashboard</a></li>\n", session_id, session_id); } } if (t->session && t->session->is_admin) { GList *g; GSS_A ("<li class='nav-header'>Administration</li>\n"); for (g = t->server->admin_resources; g; g = g_list_next (g)) { GssResource *r = (GssResource *) g->data; GSS_P ("<li %s><a href='%s%s'>%s</a></li>\n", (r == t->resource) ? "class='active'" : "", r->location, session_id, r->name); } } GSS_A ("</ul>\n" "</div><!--/.well -->\n" "</div><!--/span-->\n" "<div class='span9'>\n"); g_free (session_id); if (t->server->add_warnings) { t->server->add_warnings (t, t->server->add_warnings_priv); } }