Streaming (in) freedom
----------------------

[ I preface this article with saying that I am not an expert on media
  codecs/containers or streaming.  Rather, I am mostly an interested
  user that sometimes watches others' streams, and occasionally does
  streams of their own. ]

When thinking of 'live streaming', the idea of [computer user] freedom
may not be what immediately comes to mind.  After all, it appears that
most common streaming setups used today involve the use of SaaSS[1]
platforms like Twitch and YouTube, that coincidentally do not shy away
from sending large swaths of nonfree JavaScript code[2] to viewers'
browsers to be executed.  Rejecting these pieces of nonfree software
more often than not results in a partially or fully broken viewing
experience in the viewer's browser.

Is there any other way?  Can we stream in freedom?  Thankfully, YES!
A variety of free/libre streaming solutions exist today that respect
the freedoms of the streamer and the viewers.  This article focuses
on a setup consisting of Icecast[3] and OBS Studio[4], while briefly
mentioning a few other setups and potential problems with some of
them in 'APPENDIX A' at the end.

In a simple streaming setup, the streamer would use a program like
OBS Studio to capture and stream audio/video from their machine to
another machine -- typically a server running a streaming server
software such as Icecast -- that would receive and rebroadcast the
stream feed for the audience to listen to or watch.  We begin with
showing an excerpt from an Icecast configuration file for adding a
streaming mount point, and will then see how to configure OBS Studio
to stream to Icecast.


ICECAST

  - brief intro about icecast
  - basic streaming/icecast terminology
  - show config excerpt for mount point along with explanations


OBS STUDIO

  - brief intro about obs

  (e.g. 25.0.3 as available on Trisquel 10)

  Since as of now the 'Streaming' machinery of OBS does not support
  convenient streaming to Icecast servers out of the box, we will
  [somewhat counter-intuitively] use OBS's 'Recording' feature to
  stream to Icecast.  To do so, we have to configure 'Recording' as
  explained below.

  Open the OBS settings window.  From there, click on 'Output' in the
  left pane to open OBS's output-related settings in the right pane.
  By default, the 'Output Mode' setting at the top will likely be set
  to 'Simple', but we need to switch to the 'Advanced' mode to see the
  additional options we need to configure to be able to stream to an
  Icecast server.  After switching to advanced mode, click on the
  'Recording' tab, and fill out the fields as follows:

      Type:
          Custom Output (FFmpeg)
      FFmpeg Output Type:
          Output to URL
      File path or URL:
          icecast://user:pass@icy.example.org:8000/mnt.webm
      Container format:
          webm
      Muxer Settings (if any):
          content_type=video/webm cluster_time_limit=5100 cluster_size_limit=2M
      Video Bitrate:
          1500 Kbps
      Keyframe interval (frames):
          120

      [✓] Show all codecs (even if potentially incompatible)

      Video Encoder:
          libvpx
      Video Encoder Settings (if any):
          rt cpu-used=5 threads=2 error-resilient=1 crf=30 g=120 minrate=1.5M maxrate=1.5M
      Audio Bitrate:
          96 Kbps
      Audio Track:
          [✓] 1   [ ] 2   [ ] 3   [ ] 4   [ ] 5   [ ] 6
      Audio Encoder:
          libvorbis
      Audio Encoder Settings (if any):
          (leave empty as is)

  Brief explanations about some of the above settings and parameters:
    - in the icecast:// URL shown above,
      - 'user': TODO;
      - 'pass': TODO;
      - 'icy.example.org': the GNU/Linux server running Icecast;
      - '8000': the port Icecast is listening on; and
      - 'mnt.web': TODO.
    - cluster_time_limit
    - cluster_size_limit
    - keyframe interval (also sometimes called 'max-kf' or 'g')
    - rt
    - cpu-used
    - threads
    - error-resilient
    - crf
    - g: see 'keyframe interval' above; and
    - minrate and maxrate.

  I really like OBS Studio, but I find it an important issue that it
  cannot stream to Icecast in a simple/convenient way out of the box,
  where one has to resort to using its advanced recording options to
  do so.  One side effect of this is being unable to conveniently
  record to disk while simultaneously live streaming.  Of course, the
  keen streamer would find ways to do so (e.g. by running a local
  Icecast server acting as a primary and configured to automatically
  dump a copy of the stream to disk; and having the remote, publicly
  accessible server act as a secondary, relaying the stream from the
  private primary local server), but these workarounds will likely be
  neither as simple nor as convenient.  As such, streaming to Icecast
  should be possible out of the box using OBS Studio's 'Streaming'
  feature, with sane defaults.


OTHER

  TODO: move into APPENDIX A below.

  e.g. gstreamer-based solutions like

  - link to https://vcs.fsf.org/?p=streamdesktop.git

  but are beyond the scope of this article, as they involve describing
  complex gstreamer pipelines and their parameters all using command
  line arguments to gst-launch-1.0.  and another downside is lack of
  flexibility once start streaming (where OBS is very dynamic and
  allows easily changing many things on the fly, one cannot do that
  with the gstreamer-based script, whose parameters one cannot modify
  while live).

  Thanks to Ruben Rodriguez of the Trisquel project (formerly the CTO
  at the FSF) for his help with this/above (add Ruben's 2 examples)
  ec.sh and the other ruben sent with mic in stream


APPENDIX A - other streaming protocols/formats

  Over the years, a wide variety of protocols for streaming media have
  been developed, such as RTMP, HLS, DASH, and more.  Most of these
  protocols suffer from issues including but not limited to the ones
  listed below that limit their usefulness for the free software
  community:

  1. the protocol itself being proprietary and non-standard, thus
  limiting its adoption and implementations in free software --
  e.g. RTMP, at least initially;

  2. the protocol supporting only nonfree and/or patent-encumbered
  video formats and codecs -- e.g. HLS and RTMP; and

  3. requiring running JavaScript code in order to watch the stream in
  the browser -- e.g. DASH and HLS.  While it's possible[5] to stream
  WebM using DASH, it requires using JavaScript libraries like dash.js
  and/or video.js.  Also, in my earlier experiences watching some DASH
  streams by others, as well as some of my own earlier experiments,
  I had personally found DASH streams to be somewhat finicky/unstable.
  For instance, the audio and video falling out of sync after a while,
  or the audio feed being randomly replaced with earsplitting noise in
  a stream.  Both of these could well be due to improper configuration
  of the streaming client/server, but are nevertheless things I recall
  encountering while watching DASH streams in the past.


[1] Service as a Software Substitute:
https://www.gnu.org/philosophy/who-does-that-server-really-serve.html

[2] The JavaScript Trap:
https://www.gnu.org/philosophy/javascript-trap.html

[3] https://icecast.org

[4] https://obsproject.com

[5] see:
http://wiki.webmproject.org/adaptive-streaming/webm-dash-specification
http://wiki.webmproject.org/adaptive-streaming/instructions-to-do-webm-live-streaming-via-dash
http://wiki.webmproject.org/adaptive-streaming/instructions-to-playback-adaptive-webm-using-dash


                                 -*-

Copyright (c) 2021 bandali

Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved.  This file is offered as-is,
without any warranty.

plain text: https://bndl.org/streaming-freedom.txt