333 lines
20 KiB
HTML
333 lines
20 KiB
HTML
|
||
<!DOCTYPE html>
|
||
|
||
<html>
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||
|
||
<title>HTTP upload — Shaka Packager documentation</title>
|
||
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
|
||
<link rel="stylesheet" type="text/css" href="../_static/sphinxdoc_new.css" />
|
||
<link rel="stylesheet" type="text/css" href="../_static/graphviz.css" />
|
||
<link rel="stylesheet" type="text/css" href="../_static/table_styling.css" />
|
||
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
|
||
<script src="../_static/jquery.js"></script>
|
||
<script src="../_static/underscore.js"></script>
|
||
<script src="../_static/doctools.js"></script>
|
||
<link rel="index" title="Index" href="../genindex.html" />
|
||
<link rel="search" title="Search" href="../search.html" />
|
||
<link rel="next" title="Design" href="../design.html" />
|
||
<link rel="prev" title="FFmpeg piping" href="ffmpeg_piping.html" />
|
||
</head><body>
|
||
<div class="related" role="navigation" aria-label="related navigation">
|
||
<h3>Navigation</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="../genindex.html" title="General Index"
|
||
accesskey="I">index</a></li>
|
||
<li class="right" >
|
||
<a href="../design.html" title="Design"
|
||
accesskey="N">next</a> |</li>
|
||
<li class="right" >
|
||
<a href="ffmpeg_piping.html" title="FFmpeg piping"
|
||
accesskey="P">previous</a> |</li>
|
||
<li class="nav-item nav-item-0"><a href="../index.html">Shaka Packager documentation</a> »</li>
|
||
<li class="nav-item nav-item-1"><a href="tutorials.html" accesskey="U">Tutorials</a> »</li>
|
||
<li class="nav-item nav-item-this"><a href="">HTTP upload</a></li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="document">
|
||
<div class="documentwrapper">
|
||
<div class="bodywrapper">
|
||
<div class="body" role="main">
|
||
|
||
<blockquote>
|
||
<div><p>🛠 Status: Work in progress</p>
|
||
<p>The Shaka Packager HTTP upload feature is currently in development.
|
||
It’s on the fast track to a working alpha, so we encourage you to use
|
||
it and give us some feedback. However, there are things that haven’t
|
||
been finalized yet so you can expect some changes.</p>
|
||
<p>This document describes the current state of the implementation,
|
||
contributions are always welcome.</p>
|
||
<p>The discussion about this feature currently happens at
|
||
<a class="reference external" href="https://github.com/google/shaka-packager/issues/149">Add HTTP PUT output #149</a>.</p>
|
||
</div></blockquote>
|
||
<section id="http-upload">
|
||
<h1>HTTP upload<a class="headerlink" href="#http-upload" title="Permalink to this headline">¶</a></h1>
|
||
<section id="introduction">
|
||
<h2>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline">¶</a></h2>
|
||
<p>Shaka Packager can upload produced artefacts to a HTTP server using
|
||
HTTP PUT requests with chunked transfer encoding to improve live
|
||
publishing performance when content is not served directly from
|
||
the packaging output location. For talking HTTP, <a class="reference external" href="https://curl.haxx.se/libcurl/">libcurl</a> is used.</p>
|
||
<p>The produced artefacts are:</p>
|
||
<ul class="simple">
|
||
<li><p><a class="reference external" href="https://en.wikipedia.org/wiki/HTTP_Live_Streaming">HLS</a> playlist files in <a class="reference external" href="https://en.wikipedia.org/wiki/M3U">M3U</a> Format encoded with UTF-8 (.m3u8)</p></li>
|
||
<li><p>Chunked audio segments encoded with AAC (.aac)</p></li>
|
||
<li><p>Chunked video segments encapsulated into the
|
||
<a class="reference external" href="https://en.wikipedia.org/wiki/MPEG_transport_stream">MPEG transport stream</a> container format (.ts)</p></li>
|
||
</ul>
|
||
<section id="references">
|
||
<h3>References<a class="headerlink" href="#references" title="Permalink to this headline">¶</a></h3>
|
||
<ul class="simple">
|
||
<li><p><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6">RFC 2616 about HTTP PUT</a></p></li>
|
||
<li><p><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1">RFC 2616 about Chunked Transfer Coding</a></p></li>
|
||
</ul>
|
||
</section>
|
||
</section>
|
||
<section id="documentation">
|
||
<h2>Documentation<a class="headerlink" href="#documentation" title="Permalink to this headline">¶</a></h2>
|
||
<section id="getting-started">
|
||
<h3>Getting started<a class="headerlink" href="#getting-started" title="Permalink to this headline">¶</a></h3>
|
||
<p>To enable the HTTP upload transfer mode, use <code class="docutils literal notranslate"><span class="pre">https:</span></code> file paths for any
|
||
output files (e.g. <code class="docutils literal notranslate"><span class="pre">segment_template</span></code>).</p>
|
||
<p>All HTTP requests will be declared as
|
||
<code class="docutils literal notranslate"><span class="pre">Content-Type:</span> <span class="pre">application/octet-stream</span></code>.</p>
|
||
</section>
|
||
<section id="synopsis">
|
||
<h3>Synopsis<a class="headerlink" href="#synopsis" title="Permalink to this headline">¶</a></h3>
|
||
<p>Here is a basic example. It is similar to the “live” example and also
|
||
borrows features from “FFmpeg piping”, see <a class="reference internal" href="live.html"><span class="doc">Live</span></a> and <a class="reference internal" href="ffmpeg_piping.html"><span class="doc">FFmpeg piping</span></a>.</p>
|
||
<p>Define UNIX pipe to connect ffmpeg with packager:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>export PIPE=/tmp/bigbuckbunny.fifo
|
||
mkfifo ${PIPE}
|
||
</pre></div>
|
||
</div>
|
||
<p>Acquire and transcode RTMP stream:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span># Steady
|
||
ffmpeg -fflags nobuffer -threads 0 -y \
|
||
-i rtmp://184.72.239.149/vod/mp4:bigbuckbunny_450.mp4 \
|
||
-pix_fmt yuv420p -vcodec libx264 -preset:v superfast -acodec aac \
|
||
-f mpegts pipe: > ${PIPE}
|
||
</pre></div>
|
||
</div>
|
||
<p>Configure and run packager:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Define upload URL</span>
|
||
<span class="n">export</span> <span class="n">UPLOAD_URL</span><span class="o">=</span><span class="n">http</span><span class="p">:</span><span class="o">//</span><span class="n">localhost</span><span class="p">:</span><span class="mi">6767</span><span class="o">/</span><span class="n">hls</span><span class="o">-</span><span class="n">live</span>
|
||
|
||
<span class="c1"># Go</span>
|
||
<span class="n">packager</span> \
|
||
<span class="s2">"input=$</span><span class="si">{PIPE}</span><span class="s2">,stream=audio,segment_template=$</span><span class="si">{UPLOAD_URL}</span><span class="s2">/bigbuckbunny-audio-aac-\$Number</span><span class="si">%04d</span><span class="s2">\$.aac,playlist_name=bigbuckbunny-audio.m3u8,hls_group_id=audio"</span> \
|
||
<span class="s2">"input=$</span><span class="si">{PIPE}</span><span class="s2">,stream=video,segment_template=$</span><span class="si">{UPLOAD_URL}</span><span class="s2">/bigbuckbunny-video-h264-450-\$Number</span><span class="si">%04d</span><span class="s2">\$.ts,playlist_name=bigbuckbunny-video-450.m3u8"</span> \
|
||
<span class="o">--</span><span class="n">io_block_size</span> <span class="mi">65536</span> <span class="o">--</span><span class="n">fragment_duration</span> <span class="mi">2</span> <span class="o">--</span><span class="n">segment_duration</span> <span class="mi">2</span> \
|
||
<span class="o">--</span><span class="n">time_shift_buffer_depth</span> <span class="mi">3600</span> <span class="o">--</span><span class="n">preserved_segments_outside_live_window</span> <span class="mi">7200</span> \
|
||
<span class="o">--</span><span class="n">hls_master_playlist_output</span> <span class="s2">"$</span><span class="si">{UPLOAD_URL}</span><span class="s2">/bigbuckbunny.m3u8"</span> \
|
||
<span class="o">--</span><span class="n">hls_playlist_type</span> <span class="n">LIVE</span> \
|
||
<span class="o">--</span><span class="n">vmodule</span><span class="o">=</span><span class="n">http_file</span><span class="o">=</span><span class="mi">1</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
</section>
|
||
<section id="client-authentication">
|
||
<h2>Client Authentication<a class="headerlink" href="#client-authentication" title="Permalink to this headline">¶</a></h2>
|
||
<p>If your server requires client authentication, you can add the following
|
||
arguments to enable it:</p>
|
||
<ul class="simple">
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">--ca_file</span></code>: (optional) Absolute path to the Certificate Authority file for
|
||
the server cert. PEM format.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">--client_cert_file</span></code>: Absolute path to client certificate file.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">--client_cert_private_key_file</span></code>: Absolute path to the private Key file.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">--client_cert_private_key_password</span></code>: (optional) Password to the private
|
||
key file.</p></li>
|
||
</ul>
|
||
</section>
|
||
<section id="backlog">
|
||
<h2>Backlog<a class="headerlink" href="#backlog" title="Permalink to this headline">¶</a></h2>
|
||
<p>Please note the HTTP upload feature still lacks some features
|
||
probably important for production. Contributions are welcome!</p>
|
||
<section id="http-delete">
|
||
<h3>HTTP DELETE<a class="headerlink" href="#http-delete" title="Permalink to this headline">¶</a></h3>
|
||
<p>Nothing has be done to support this yet:</p>
|
||
<blockquote>
|
||
<div><p>Packager supports removing old segments automatically.
|
||
See <code class="docutils literal notranslate"><span class="pre">preserved_segments_outside_live_window</span></code> option in
|
||
<a class="reference external" href="https://en.wikipedia.org/wiki/Dynamic_Adaptive_Streaming_over_HTTP">DASH</a> options or <a class="reference external" href="https://en.wikipedia.org/wiki/HTTP_Live_Streaming">HLS</a> options for details.</p>
|
||
</div></blockquote>
|
||
</section>
|
||
<section id="software-tests">
|
||
<h3>Software tests<a class="headerlink" href="#software-tests" title="Permalink to this headline">¶</a></h3>
|
||
<p>We should do some minimal QA, check whether the test
|
||
suite breaks and maybe add some tests covering new code.</p>
|
||
</section>
|
||
<section id="network-timeouts">
|
||
<h3>Network timeouts<a class="headerlink" href="#network-timeouts" title="Permalink to this headline">¶</a></h3>
|
||
<p><a class="reference external" href="https://curl.haxx.se/libcurl/">libcurl</a> can apply network timeout settings. However,
|
||
we haven’t addressed this yet.</p>
|
||
</section>
|
||
<section id="miscellaneous">
|
||
<h3>Miscellaneous<a class="headerlink" href="#miscellaneous" title="Permalink to this headline">¶</a></h3>
|
||
<ul class="simple">
|
||
<li><p>Address all things TODO and FIXME</p></li>
|
||
<li><p>Make <code class="docutils literal notranslate"><span class="pre">io_cache_size</span></code> configurable?</p></li>
|
||
</ul>
|
||
</section>
|
||
</section>
|
||
<section id="example-backend">
|
||
<h2>Example Backend<a class="headerlink" href="#example-backend" title="Permalink to this headline">¶</a></h2>
|
||
<section id="http-put-file-uploads-to-nginx">
|
||
<h3>HTTP PUT file uploads to Nginx<a class="headerlink" href="#http-put-file-uploads-to-nginx" title="Permalink to this headline">¶</a></h3>
|
||
<p>The receiver is based on the native <a class="reference external" href="http://nginx.org/">Nginx</a> module “<a class="reference external" href="http://nginx.org/en/docs/http/ngx_http_dav_module.html">ngx_http_dav_module</a>”,
|
||
it handles HTTP PUT requests with chunked transfer encoding
|
||
like emitted by Shaka Packager.</p>
|
||
<p>The configuration is very simple:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>server {
|
||
listen 6767 default_server;
|
||
|
||
access_log /dev/stdout combined;
|
||
error_log /dev/stdout info;
|
||
|
||
root /var/spool;
|
||
location ~ ^/hls-live/(.+)$ {
|
||
|
||
dav_methods PUT;
|
||
create_full_put_path on;
|
||
|
||
proxy_buffering off;
|
||
client_max_body_size 20m;
|
||
|
||
}
|
||
|
||
}
|
||
</pre></div>
|
||
</div>
|
||
<p>Run Nginx:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>nginx -p `pwd` -c nginx.conf -g "daemon off;"
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="http-put-file-uploads-to-caddy">
|
||
<h3>HTTP PUT file uploads to Caddy<a class="headerlink" href="#http-put-file-uploads-to-caddy" title="Permalink to this headline">¶</a></h3>
|
||
<p>The receiver is based on the <a class="reference external" href="https://caddyserver.com/">Caddy</a> webserver, it handles HTTP PUT
|
||
requests with chunked transfer encoding like emitted by Shaka Packager.</p>
|
||
<p>Put this configuration into a <cite>Caddyfile</cite>:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Bind address</span>
|
||
<span class="p">:</span><span class="mi">6767</span>
|
||
|
||
<span class="c1"># Enable logging</span>
|
||
<span class="n">log</span> <span class="n">stdout</span>
|
||
|
||
<span class="c1"># Web server root with autoindex</span>
|
||
<span class="n">root</span> <span class="o">/</span><span class="n">var</span><span class="o">/</span><span class="n">spool</span>
|
||
<span class="n">redir</span> <span class="o">/</span><span class="n">hls</span><span class="o">-</span><span class="n">live</span> <span class="p">{</span>
|
||
<span class="k">if</span> <span class="p">{</span><span class="n">path</span><span class="p">}</span> <span class="ow">is</span> <span class="s2">"/"</span>
|
||
<span class="p">}</span>
|
||
<span class="n">browse</span>
|
||
|
||
<span class="c1"># Enable upload with HTTP PUT</span>
|
||
<span class="n">upload</span> <span class="o">/</span><span class="n">hls</span><span class="o">-</span><span class="n">live</span> <span class="p">{</span>
|
||
<span class="n">to</span> <span class="s2">"/var/spool/hls-live"</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Run Caddy:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">caddy</span> <span class="o">-</span><span class="n">conf</span> <span class="n">Caddyfile</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
</section>
|
||
<section id="development-and-debugging">
|
||
<h2>Development and debugging<a class="headerlink" href="#development-and-debugging" title="Permalink to this headline">¶</a></h2>
|
||
<p>Watch the network:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ngrep</span> <span class="o">-</span><span class="n">Wbyline</span> <span class="o">-</span><span class="n">dlo</span> <span class="n">port</span> <span class="mi">6767</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Grab and run <a class="reference external" href="https://gist.github.com/amotl/3ed38e461af743aeeade5a5a106c1296">httpd-reflector.py</a> to use it as a dummy HTTP sink:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Ready</span>
|
||
<span class="n">wget</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">gist</span><span class="o">.</span><span class="n">githubusercontent</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">amotl</span><span class="o">/</span><span class="mi">3</span><span class="n">ed38e461af743aeeade5a5a106c1296</span><span class="o">/</span><span class="n">raw</span><span class="o">/</span><span class="n">httpd</span><span class="o">-</span><span class="n">reflector</span><span class="o">.</span><span class="n">py</span>
|
||
<span class="n">chmod</span> <span class="o">+</span><span class="n">x</span> <span class="n">httpd</span><span class="o">-</span><span class="n">reflector</span><span class="o">.</span><span class="n">py</span>
|
||
<span class="o">./</span><span class="n">httpd</span><span class="o">-</span><span class="n">reflector</span><span class="o">.</span><span class="n">py</span> <span class="o">--</span><span class="n">port</span> <span class="mi">6767</span>
|
||
</pre></div>
|
||
</div>
|
||
<hr class="docutils" />
|
||
</section>
|
||
</section>
|
||
|
||
|
||
<div class="clearer"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||
<div class="sphinxsidebarwrapper">
|
||
<h3><a href="../index.html">Table of Contents</a></h3>
|
||
<ul>
|
||
<li><a class="reference internal" href="#">HTTP upload</a><ul>
|
||
<li><a class="reference internal" href="#introduction">Introduction</a><ul>
|
||
<li><a class="reference internal" href="#references">References</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#documentation">Documentation</a><ul>
|
||
<li><a class="reference internal" href="#getting-started">Getting started</a></li>
|
||
<li><a class="reference internal" href="#synopsis">Synopsis</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#client-authentication">Client Authentication</a></li>
|
||
<li><a class="reference internal" href="#backlog">Backlog</a><ul>
|
||
<li><a class="reference internal" href="#http-delete">HTTP DELETE</a></li>
|
||
<li><a class="reference internal" href="#software-tests">Software tests</a></li>
|
||
<li><a class="reference internal" href="#network-timeouts">Network timeouts</a></li>
|
||
<li><a class="reference internal" href="#miscellaneous">Miscellaneous</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#example-backend">Example Backend</a><ul>
|
||
<li><a class="reference internal" href="#http-put-file-uploads-to-nginx">HTTP PUT file uploads to Nginx</a></li>
|
||
<li><a class="reference internal" href="#http-put-file-uploads-to-caddy">HTTP PUT file uploads to Caddy</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#development-and-debugging">Development and debugging</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<h4>Previous topic</h4>
|
||
<p class="topless"><a href="ffmpeg_piping.html"
|
||
title="previous chapter">FFmpeg piping</a></p>
|
||
<h4>Next topic</h4>
|
||
<p class="topless"><a href="../design.html"
|
||
title="next chapter">Design</a></p>
|
||
<div role="note" aria-label="source link">
|
||
<h3>This Page</h3>
|
||
<ul class="this-page-menu">
|
||
<li><a href="../_sources/tutorials/http_upload.rst.txt"
|
||
rel="nofollow">Show Source</a></li>
|
||
</ul>
|
||
</div>
|
||
<div id="searchbox" style="display: none" role="search">
|
||
<h3 id="searchlabel">Quick search</h3>
|
||
<div class="searchformwrapper">
|
||
<form class="search" action="../search.html" method="get">
|
||
<input type="text" name="q" aria-labelledby="searchlabel" />
|
||
<input type="submit" value="Go" />
|
||
</form>
|
||
</div>
|
||
</div>
|
||
<script>$('#searchbox').show(0);</script>
|
||
</div>
|
||
</div>
|
||
<div class="clearer"></div>
|
||
</div>
|
||
<div class="related" role="navigation" aria-label="related navigation">
|
||
<h3>Navigation</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="../genindex.html" title="General Index"
|
||
>index</a></li>
|
||
<li class="right" >
|
||
<a href="../design.html" title="Design"
|
||
>next</a> |</li>
|
||
<li class="right" >
|
||
<a href="ffmpeg_piping.html" title="FFmpeg piping"
|
||
>previous</a> |</li>
|
||
<li class="nav-item nav-item-0"><a href="../index.html">Shaka Packager documentation</a> »</li>
|
||
<li class="nav-item nav-item-1"><a href="tutorials.html" >Tutorials</a> »</li>
|
||
<li class="nav-item nav-item-this"><a href="">HTTP upload</a></li>
|
||
</ul>
|
||
</div>
|
||
<div class="footer" role="contentinfo">
|
||
© Copyright 2017, Google.
|
||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 4.0.2.
|
||
</div>
|
||
</body>
|
||
</html> |