Skip to content

Instantly share code, notes, and snippets.

@niko
Forked from ePirat/spec.md
Last active February 28, 2026 11:42
Show Gist options
  • Select an option

  • Save niko/2a1d7b2d109ebe7f7ca2f860c3505ef0 to your computer and use it in GitHub Desktop.

Select an option

Save niko/2a1d7b2d109ebe7f7ca2f860c3505ef0 to your computer and use it in GitHub Desktop.

Revisions

  1. Niko Dittmann revised this gist Oct 31, 2024. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion icy_meta.md
    Original file line number Diff line number Diff line change
    @@ -27,7 +27,7 @@ icy-br: 128
    icy-metaint: 16000
    xxx then here comes 16k of mp3 bytes …
    02StreamTitle='A nice song';StreamUrl=''00000 <- padded with 0-bytes up to 2*32 bytes of metadata
    02StreamTitle='A nice song';StreamUrl=''00000 <- padded with 0-bytes up to 2*16 bytes of metadata
    xxx then here comes another 16k of mp3 bytes …
    0 <- the metadata usually only gets sent once
    xxx then here comes yet another 16k of mp3 bytes …
    @@ -47,6 +47,8 @@ curl -s -H 'Icy-Metadata: 1' stream.domain.com/mountpoint | head -c 16128 | tail
    ```
    Here you can see the first byte `3` indicating that 3*16 = 48 bytes of metadata are following. The metadata has the important `StreamTitle` field which ends with `';`. The rest of the 48 bytes is `0`-padded.

    The maximum metadata length seems to be 255 (see https://github.com/xiph/Icecast-Server/blob/57093def7baacf2aaaff3a17915cd7fc0b8cfec3/src/format_mp3.c#L291). I haven't found that in any spec though. Any hints appreciated.

    A very basic icy metadata parser in ruby looks like the attached icy.rb. It consumes a stream on STDIN, outputs metadata and information on STDERR and the actuall mp3 data on STDOUT. I can be used like this:

    ```
  2. Niko Dittmann revised this gist Dec 14, 2020. 1 changed file with 3 additions and 2 deletions.
    5 changes: 3 additions & 2 deletions icy_meta.md
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,8 @@
    Transmittion metadata _within_ the stream from an icecast server to a client basically works like this:

    * The client adds an HTTP header to the request indicating that it is able to process in-band metadata: `Icy-Metadata: 1`.
    * The server _may_ then splice the metadata into the stream. If it does so, it has to tell the client the frequency with wich metadata is added. That's also done via an HTTP header: `icy-metaint: 16000`. 16000 a safe bet. All clients I've seen are OK with that. For higher precision with known clients (for example when relaying a stream) you can try to use 1000. The metadata then gets just cut into the stream every `icy-metaint` bytes.
    * The server _may_ then splice the metadata into the stream. If it does so, it _has_ to tell the client the frequency with wich metadata is added. That's also done via an HTTP header: `icy-metaint: 16000`. 16000 is a safe bet. All clients I've seen are OK with that. For higher precision with known clients (for example when relaying a stream) you can try to use 1000.
    * The metadata then gets just cut into the stream every `icy-metaint` bytes.
    * The metadata block starts with a single byte indicating how long the metadata is. This byte must be multiplied with 16 for the actual size. Then the metadata follows.
    * The metadata itself may have several fields, but the only crucial one is `StreamTitle`. I have yet to see a client that supports _anything_ else.

    @@ -33,7 +34,7 @@ xxx then here comes yet another 16k of mp3 bytes …
    ```

    The most unsophisticated way to extract metadata from stream with icy-metaint: 16000 looks like this:
    The most unsophisticated way to extract the first metadata block from stream with icy-metaint: 16000 looks like this:

    ```
    curl -s -H 'Icy-Metadata: 1' stream.domain.com/mountpoint | head -c 16128 | tail -c 128 | hexdump -C
  3. Niko Dittmann revised this gist Dec 14, 2020. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -2,4 +2,5 @@ An collection of documents about icecast/shoutcast streaming.

    * icy_meta.md contains the basics of metadata within the stream. The document where I got this information from (http://www.smackfu.com/stuff/programming/shoutcast.html) is not available any more.
    * spec.md is a copy of this gist https://gist.github.com/ePirat/adc3b8ba00d85b7e3870 just to prevent the informtation from disappearing. You may find the discussion beneath the original gist interresting as well.
    * icy.rb is the most simple icy metadata parser written in Ruby.
    * icy.rb is the most simple icy metadata parser written in Ruby.
    * Some information can be found here: https://cast.readme.io/docs/icy
  4. Niko Dittmann revised this gist Dec 14, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion icy_meta.md
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    Transmittion metadata _within_ the stream from an icecast server to a client basically works like this:

    * The client adds an HTTP header to the request indicating that it is able to process in-band metadata: `Icy-Metadata: 1`.
    * The server _may_ then splice the metadata into the stream. If it does so, it has to tell the client the frequency with wich metadata is added. That's also done via an HTTP header: `icy-metaint: 16000`. 16000 a save bet. All clients I've seen are OK with that. For higher precision with known clients (for example when relaying a stream) you can try to use 1000. The metadata then gets just cut into the stream every `icy-metaint` bytes.
    * The server _may_ then splice the metadata into the stream. If it does so, it has to tell the client the frequency with wich metadata is added. That's also done via an HTTP header: `icy-metaint: 16000`. 16000 a safe bet. All clients I've seen are OK with that. For higher precision with known clients (for example when relaying a stream) you can try to use 1000. The metadata then gets just cut into the stream every `icy-metaint` bytes.
    * The metadata block starts with a single byte indicating how long the metadata is. This byte must be multiplied with 16 for the actual size. Then the metadata follows.
    * The metadata itself may have several fields, but the only crucial one is `StreamTitle`. I have yet to see a client that supports _anything_ else.

  5. Niko Dittmann revised this gist Dec 14, 2020. 1 changed file with 3 additions and 2 deletions.
    5 changes: 3 additions & 2 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,5 @@
    An collection of documents about icecast/shoutcast streaming.

    icy_meta.md contains the basics of metadata within the stream. The document where I got this information from (http://www.smackfu.com/stuff/programming/shoutcast.html) is not available any more.
    spec.md is a copy of this gist https://gist.github.com/ePirat/adc3b8ba00d85b7e3870 just prevent the informtation from disappearing. You may find the discussion beneath the original gist interresting as well.
    * icy_meta.md contains the basics of metadata within the stream. The document where I got this information from (http://www.smackfu.com/stuff/programming/shoutcast.html) is not available any more.
    * spec.md is a copy of this gist https://gist.github.com/ePirat/adc3b8ba00d85b7e3870 just to prevent the informtation from disappearing. You may find the discussion beneath the original gist interresting as well.
    * icy.rb is the most simple icy metadata parser written in Ruby.
  6. Niko Dittmann revised this gist Dec 14, 2020. 2 changed files with 23 additions and 7 deletions.
    4 changes: 4 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,4 @@
    An collection of documents about icecast/shoutcast streaming.

    icy_meta.md contains the basics of metadata within the stream. The document where I got this information from (http://www.smackfu.com/stuff/programming/shoutcast.html) is not available any more.
    spec.md is a copy of this gist https://gist.github.com/ePirat/adc3b8ba00d85b7e3870 just prevent the informtation from disappearing. You may find the discussion beneath the original gist interresting as well.
    26 changes: 19 additions & 7 deletions icy_meta.md
    Original file line number Diff line number Diff line change
    @@ -1,11 +1,9 @@
    There once was very detailed information about how metadata is transmitted _within_ the stream from an icecast server to a client here: http://www.smackfu.com/stuff/programming/shoutcast.html This document does not seem to be available any more.
    Transmittion metadata _within_ the stream from an icecast server to a client basically works like this:

    Basically it's like this:

    * The client add an HTTP header to the request indicating that it is able to process in-band metadata: `Icy-Metadata: 1`.
    * The client adds an HTTP header to the request indicating that it is able to process in-band metadata: `Icy-Metadata: 1`.
    * The server _may_ then splice the metadata into the stream. If it does so, it has to tell the client the frequency with wich metadata is added. That's also done via an HTTP header: `icy-metaint: 16000`. 16000 a save bet. All clients I've seen are OK with that. For higher precision with known clients (for example when relaying a stream) you can try to use 1000. The metadata then gets just cut into the stream every `icy-metaint` bytes.
    * The metadata block itself starts with a single byte indicating how long the metadata is. This byte must be multiplied with 16 for the actual size. Then the metadata follows.
    * The metadata may have several fields, but the only crucial one is `StreamTitle`. I have yet to see a client that supports _anything_ else.
    * The metadata block starts with a single byte indicating how long the metadata is. This byte must be multiplied with 16 for the actual size. Then the metadata follows.
    * The metadata itself may have several fields, but the only crucial one is `StreamTitle`. I have yet to see a client that supports _anything_ else.

    So a request/response may basically look like this:

    @@ -35,8 +33,22 @@ xxx then here comes yet another 16k of mp3 bytes …
    ```

    The most unsophisticated way to extract metadata from stream with icy-metaint: 16000 looks like this:

    ```
    curl -s -H 'Icy-Metadata: 1' stream.domain.com/mountpoint | head -c 16128 | tail -c 128 | hexdump -C
    00000000 03 53 74 72 65 61 6d 54 69 74 6c 65 3d 27 44 69 |.StreamTitle='Di|
    00000010 65 20 46 61 6e 74 61 73 74 69 73 63 68 65 6e 20 |e Fantastischen |
    00000020 56 69 65 72 20 2d 20 52 65 69 63 68 27 3b 00 00 |Vier - Reich';..|
    00000030 00 82 98 b0 e1 45 48 58 3c 01 e6 79 0a af 15 50 |.....EHX<..y...P|
    00000040 66 52 c1 b7 f0 f3 45 4f 27 21 0e 0a 19 2f a9 24 |fR....EO'!.../.$|
    00000050 93 24 88 24 10 e7 98 e6 3f 3e cb 53 af ad c0 00 |.$.$....?>.S....|
    ```
    Here you can see the first byte `3` indicating that 3*16 = 48 bytes of metadata are following. The metadata has the important `StreamTitle` field which ends with `';`. The rest of the 48 bytes is `0`-padded.

    A very basic icy metadata parser in ruby looks like the attached icy.rb. It consumes a stream on STDIN, outputs metadata and information on STDERR and the actuall mp3 data on STDOUT. I can be used like this:

    ```
    curl -s -H 'Icy-Metadata: 1' 'http://stream.domain.com/mountpoint' | ruby icy.rb | mpg123 -
    ```
    ```
    Note that you can (and have to) pass a metaint different from 16000 as first argument to the ruby script.
  7. Niko Dittmann revised this gist Dec 14, 2020. 2 changed files with 28 additions and 0 deletions.
    22 changes: 22 additions & 0 deletions icy.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,22 @@
    metaint = ARGV.first && ARGV.first.to_i || 16000

    STDERR.puts "metaint: #{metaint}"

    i = 0
    started_at = Time.now
    streamed_bytes = 0
    while b = STDIN.read(1)

    if i == metaint
    metalength = b.bytes.first.to_i * 16
    meta = STDIN.read metalength
    meta.force_encoding 'utf-8'
    STDERR.puts "#{metalength}:#{meta.bytesize} #{(streamed_bytes/(Time.now - started_at)).to_i}b/s #{meta}"

    i = 0
    else
    STDOUT.print b
    i += 1
    streamed_bytes += 1
    end
    end
    6 changes: 6 additions & 0 deletions icy_meta.md
    Original file line number Diff line number Diff line change
    @@ -33,4 +33,10 @@ xxx then here comes another 16k of mp3 bytes …
    0 <- the metadata usually only gets sent once
    xxx then here comes yet another 16k of mp3 bytes …
    ```

    A very basic icy metadata parser in ruby looks like the attached icy.rb. It consumes a stream on STDIN, outputs metadata and information on STDERR and the actuall mp3 data on STDOUT. I can be used like this:

    ```
    curl -s -H 'Icy-Metadata: 1' 'http://stream.domain.com/mountpoint' | ruby icy.rb | mpg123 -
    ```
  8. Niko Dittmann revised this gist Dec 14, 2020. 1 changed file with 36 additions and 0 deletions.
    36 changes: 36 additions & 0 deletions icy_meta.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,36 @@
    There once was very detailed information about how metadata is transmitted _within_ the stream from an icecast server to a client here: http://www.smackfu.com/stuff/programming/shoutcast.html This document does not seem to be available any more.

    Basically it's like this:

    * The client add an HTTP header to the request indicating that it is able to process in-band metadata: `Icy-Metadata: 1`.
    * The server _may_ then splice the metadata into the stream. If it does so, it has to tell the client the frequency with wich metadata is added. That's also done via an HTTP header: `icy-metaint: 16000`. 16000 a save bet. All clients I've seen are OK with that. For higher precision with known clients (for example when relaying a stream) you can try to use 1000. The metadata then gets just cut into the stream every `icy-metaint` bytes.
    * The metadata block itself starts with a single byte indicating how long the metadata is. This byte must be multiplied with 16 for the actual size. Then the metadata follows.
    * The metadata may have several fields, but the only crucial one is `StreamTitle`. I have yet to see a client that supports _anything_ else.

    So a request/response may basically look like this:

    ```
    $ curl -i -H 'Icy-Metadata: 1' http://stream.domain.com/mountpoint
    HTTP/1.1 200 OK
    Date: Mon, 14 Dec 2020 14:19:59 GMT
    Content-Type: audio/mpeg
    Transfer-Encoding: chunked
    Connection: keep-alive
    icy-name: Mountpoint
    icy-url: http://domain.com/mountpoint
    icy-description: My webradio station
    icy-genre: Pop
    icy-pub: 1
    icy-sr: 44100
    icy-audio-info: ice-channels=2;ice-samplerate=44100;ice-bitrate=128
    Server: whatevercast 12.5
    icy-br: 128
    icy-metaint: 16000
    xxx then here comes 16k of mp3 bytes …
    02StreamTitle='A nice song';StreamUrl=''00000 <- padded with 0-bytes up to 2*32 bytes of metadata
    xxx then here comes another 16k of mp3 bytes …
    0 <- the metadata usually only gets sent once
    xxx then here comes yet another 16k of mp3 bytes …
    ```
  9. @ePirat ePirat revised this gist Jan 31, 2017. 1 changed file with 64 additions and 22 deletions.
    86 changes: 64 additions & 22 deletions spec.md
    Original file line number Diff line number Diff line change
    @@ -18,31 +18,33 @@ followed by a whitespace and then the username and password separated by a colon
    The mountpoint itself is specified as the path part of the URL.
    Additional mountpoint information can be set using specific (non-standard) HTTP headers:

    ice-public
    : For a mountpoint that doesn't has `<public>` configured, this influences if the mountpoint shoult be advertised to a YP directory or not. Value can either be `0` (not public) or `1` (public).
    <dl>
    <dt>ice-public</dt>
    <dd>For a mountpoint that doesn't has <code>&lt;public&gt;</code> configured, this influences if the mountpoint shoult be advertised to a YP directory or not.<br />Value can either be <code>0</code> (not public) or <code>1</code> (public).</dd>

    ice-name
    : For a mountpoint that doesn't has `<stream-name>` configure, this sets the name of the stream.
    <dt>ice-name</dt>
    <dd>For a mountpoint that doesn't has <code>&lt;stream-name&gt;</code> configured, this sets the name of the stream.</dd>

    ice-description
    : For a mountpoint that doesn't has `<stream-description>` configure, this sets the description of the stream.
    <dt>ice-description</dt>
    <dd>For a mountpoint that doesn't has <code>&lt;stream-description&gt;</code> configured, this sets the description of the stream.</dd>

    ice-url
    : For a mountpoint that doesn't has `<stream-url>` configure, this sets the URL to the Website of the stream. (This should _not_ be the Server or mountpoint URL)
    <dt>ice-url</dt>
    <dd>For a mountpoint that doesn't has <code>&lt;stream-url&gt;</code> configure, this sets the URL to the Website of the stream. (This should _not_ be the Server or mountpoint URL)</dd>

    ice-genre
    : For a mountpoint that doesn't has `<genre>` configure, this sets the genre of the stream.
    <dt>ice-genre</dt>
    <dd>For a mountpoint that doesn't has <code>&lt;genre&gt;</code> configure, this sets the genre of the stream.</dd>

    ice-bitrate
    : This sets the bitrate of the stream.
    <dt>ice-bitrate</dt>
    <dd>This sets the bitrate of the stream.</dd>

    ice-audio-info
    : A Key-Value list of audio information about the stream, using `=` as separator between key and value and `;` as separator of the Key-Value pairs.
    Values must be URL-encoded if necessary.
    Example: `samplerate=44100;quality=10%2e0;channels=2`
    <dt>ice-audio-info</dt>
    <dd>A Key-Value list of audio information about the stream, using <code>=</code> as separator between key and value and <code>;</code> as separator of the Key-Value pairs.<br />
    Values must be URL-encoded if necessary.<br />
    Example: <code>samplerate=44100;quality=10%2e0;channels=2</code></dd>

    Content-Type
    : Indicates the content type of the stream, this must be set.
    <dt>Content-Type</dt>
    <dd>Indicates the content type of the stream, this must be set.</dd>
    </dl>

    ### Sending data
    Data is sent as usual in the body of the request, but it has to be sent at the right timing. This means if the source client sends data to Icecast that is already completely avaliable, it may not sent all the data right away, else Icecast will not be able to keep up. The source client is expected to sent the data as if it is live.
    @@ -101,12 +103,16 @@ In case of the `PUT` method being used with older Icecast versions that do not s
    `<` Indicates what is sent from the **server to** the **client**
    `>` Indicates what is sent from the **client to** the **server**

    ### PUT

    ```
    > PUT /testsendung.mp3 HTTP/1.1
    > Authorization: Basic REDACTED=
    > Host: example.com:8001
    > PUT /stream.mp3 HTTP/1.1
    > Host: example.com:8000
    > Authorization: Basic c291cmNlOmhhY2ttZQ==
    > User-Agent: curl/7.51.0
    > Accept: */*
    > Content-Type: audio/ogg
    > Transfer-Encoding: chunked
    > Content-Type: audio/mpeg
    > Ice-Public: 1
    > Ice-Name: Teststream
    > Ice-Description: This is just a simple test stream
    @@ -115,6 +121,42 @@ In case of the `PUT` method being used with older Icecast versions that do not s
    > Expect: 100-continue
    >
    < HTTP/1.1 100 Continue
    < Server: Icecast 2.5.0
    < Connection: Close
    < Accept-Encoding: identity
    < Allow: GET, SOURCE
    < Date: Tue, 31 Jan 2017 21:26:37 GMT
    < Cache-Control: no-cache
    < Expires: Mon, 26 Jul 1997 05:00:00 GMT
    < Pragma: no-cache
    < Access-Control-Allow-Origin: *
    > [ Stream data sent by cient ]
    < HTTP/1.0 200 OK
    ```

    ### SOURCE
    ```
    > SOURCE /stream.mp3 HTTP/1.1
    > Host: example.com:8000
    > Authorization: Basic c291cmNlOmhhY2ttZQ==
    > User-Agent: curl/7.51.0
    > Accept: */*
    > Content-Type: audio/mpeg
    > Ice-Public: 1
    > Ice-Name: Teststream
    > Ice-Description: This is just a simple test stream
    > Ice-URL: http://example.org
    > Ice-Genre: Rock
    >
    < HTTP/1.0 200 OK
    < Server: Icecast 2.5.0
    < Connection: Close
    < Allow: GET, SOURCE
    < Date: Tue, 31 Jan 2017 21:26:13 GMT
    < Cache-Control: no-cache
    < Expires: Mon, 26 Jul 1997 05:00:00 GMT
    < Pragma: no-cache
    < Access-Control-Allow-Origin: *
    <
    > [ Stream data sent by cient ]
    ```
  10. @ePirat ePirat revised this gist Nov 11, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion spec.md
    Original file line number Diff line number Diff line change
    @@ -98,7 +98,7 @@ In case of the `PUT` method being used with older Icecast versions that do not s

    ## Example request

    `<` Indicates what is sent from the **server to** the **client**
    `<` Indicates what is sent from the **server to** the **client**
    `>` Indicates what is sent from the **client to** the **server**

    ```
  11. @ePirat ePirat revised this gist Nov 11, 2014. 1 changed file with 24 additions and 1 deletion.
    25 changes: 24 additions & 1 deletion spec.md
    Original file line number Diff line number Diff line change
    @@ -94,4 +94,27 @@ The SOURCE method is deprecated since 2.4.0 and should not be used anymore. It w
    ## Which method to use
    Since the old `SOURCE` method is deprecated, a client should try both, first `PUT` and then fall back to `SOURCE` if the `PUT` method doesn't work.

    In case of the `PUT` method being used with older Icecast versions that do not support it (< 2.4.0), Icecast will return an empty reply, this means, no status code or headers or body is sent.
    In case of the `PUT` method being used with older Icecast versions that do not support it (< 2.4.0), Icecast will return an empty reply, this means, no status code or headers or body is sent.

    ## Example request

    `<` Indicates what is sent from the **server to** the **client**
    `>` Indicates what is sent from the **client to** the **server**

    ```
    > PUT /testsendung.mp3 HTTP/1.1
    > Authorization: Basic REDACTED=
    > Host: example.com:8001
    > Accept: */*
    > Content-Type: audio/ogg
    > Ice-Public: 1
    > Ice-Name: Teststream
    > Ice-Description: This is just a simple test stream
    > Ice-URL: http://example.org
    > Ice-Genre: Rock
    > Expect: 100-continue
    >
    < HTTP/1.1 100 Continue
    < HTTP/1.0 200 OK
    > [ Stream data sent by cient ]
    ```
  12. @ePirat ePirat revised this gist Nov 10, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion spec.md
    Original file line number Diff line number Diff line change
    @@ -50,7 +50,7 @@ Another important thing to note is that Icecast currently doesn't support chunke

    ### Common status codes
    Icecast reponds with valid HTTP Status codes, and a message, indicating what was wrong in case of error.
    In case of success it sends status code `200` with message `OK`. Any HTTP error can happen. This is an incomplet list listing most common status codes and possible errors.
    In case of success it sends status code `200` with message `OK`. Any HTTP error can happen. This is an not exhaustive list, might change in future versions, listing most common status codes and possible errors.

    200 OK
    : Everything ok
  13. @ePirat ePirat revised this gist Nov 10, 2014. 1 changed file with 6 additions and 4 deletions.
    10 changes: 6 additions & 4 deletions spec.md
    Original file line number Diff line number Diff line change
    @@ -79,17 +79,19 @@ In case of success it sends status code `200` with message `OK`. Any HTTP error
    500 Internal Server Error
    : An internal Icecast error happened, there is nothing that the client can do about it.

    If anything goes wrong, the source client should show a helpful error message to the user, so that he knows what happened.
    If anything goes wrong, the source client should show a helpful error message, so that it's known what happened.
    Do __not__ shows generic messages like "An error has occured" or "Connection to Icecast failed" if it is possible to
    provide more details.
    provide more details. It is good practice to always display the code and message to the user.

    For example, a good error message for `403 Mountpoint in use` would be:
    "Couldn't connect to Icecast, because the specified mountpoint is already in use."
    "Couldn't connect to Icecast, because the specified mountpoint is already in use. (403 Mountpoint in use)"

    ## HTTP SOURCE based protocol
    Older Icecast servers prior to 2.4.0 used a custom HTTP method for source clients, called `SOURCE`.
    It is nearly equal to the above described PUT method, but doesn't has support for the `100-continue` header.
    The SOURCE method is deprecated since 2.4.0 and should not be used anymore. It will propably be removed in a future version.

    ## Which method to use
    Since the old `SOURCE` method is deprecated, a client should try both, first `PUT` and then fall back to `SOURCE` if the `PUT` method doesn't work.
    Since the old `SOURCE` method is deprecated, a client should try both, first `PUT` and then fall back to `SOURCE` if the `PUT` method doesn't work.

    In case of the `PUT` method being used with older Icecast versions that do not support it (< 2.4.0), Icecast will return an empty reply, this means, no status code or headers or body is sent.
  14. @ePirat ePirat revised this gist Nov 10, 2014. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions spec.md
    Original file line number Diff line number Diff line change
    @@ -48,9 +48,9 @@ Content-Type
    Data is sent as usual in the body of the request, but it has to be sent at the right timing. This means if the source client sends data to Icecast that is already completely avaliable, it may not sent all the data right away, else Icecast will not be able to keep up. The source client is expected to sent the data as if it is live.
    Another important thing to note is that Icecast currently doesn't support chunked transfer encoding!

    ### Error codes
    ### Common status codes
    Icecast reponds with valid HTTP Status codes, and a message, indicating what was wrong in case of error.
    In case of success it sends status code `200` with message `OK`. Below there is a full list of status codes and possible errors.
    In case of success it sends status code `200` with message `OK`. Any HTTP error can happen. This is an incomplet list listing most common status codes and possible errors.

    200 OK
    : Everything ok
  15. @ePirat ePirat revised this gist Nov 10, 2014. 1 changed file with 9 additions and 9 deletions.
    18 changes: 9 additions & 9 deletions spec.md
    Original file line number Diff line number Diff line change
    @@ -52,31 +52,31 @@ Another important thing to note is that Icecast currently doesn't support chunke
    Icecast reponds with valid HTTP Status codes, and a message, indicating what was wrong in case of error.
    In case of success it sends status code `200` with message `OK`. Below there is a full list of status codes and possible errors.

    `200 OK`
    200 OK
    : Everything ok

    `100 Continue`
    100 Continue
    : This is sent in case a `Request: 100-continue` header was sent by the client and everything is ok. It indicates that the client can go on and send data.

    `401 You need to authenticate`
    401 You need to authenticate
    : No auth information sent or credentials wrong.

    `403 Content-type not supported`
    403 Content-type not supported
    : The supplied Content-Type is not supported by Icecast.

    `403 No Content-type given`
    403 No Content-type given
    : There was no Content-Type given. The source client is required to send a Content-Type.

    `403 internal format allocation problem`
    403 internal format allocation problem
    : There was a problem allocating the format handler, this is an internal Icecast problem.

    `403 too many sources connected`
    403 too many sources connected
    : The configured source client connection limit was reached and no more source clients can connect at the moment.

    `403 Mountpoint in use`
    403 Mountpoint in use
    : The mountpoint the client tried to connect too is already used by another client.

    `500 Internal Server Error`
    500 Internal Server Error
    : An internal Icecast error happened, there is nothing that the client can do about it.

    If anything goes wrong, the source client should show a helpful error message to the user, so that he knows what happened.
  16. @ePirat ePirat revised this gist Nov 10, 2014. 1 changed file with 14 additions and 2 deletions.
    16 changes: 14 additions & 2 deletions spec.md
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    # Icecast protocol specification

    ## What is the Icecast protocol?
    When speaking of the Icecast protocol here, actually it's just the HTTP protocol, and here we will explain futher how
    When speaking of the Icecast protocol here, actually it's just the HTTP protocol, and this document will explain further how
    source clients need to send data to Icecast.

    ## HTTP PUT based protocol
    @@ -46,6 +46,7 @@ Content-Type

    ### Sending data
    Data is sent as usual in the body of the request, but it has to be sent at the right timing. This means if the source client sends data to Icecast that is already completely avaliable, it may not sent all the data right away, else Icecast will not be able to keep up. The source client is expected to sent the data as if it is live.
    Another important thing to note is that Icecast currently doesn't support chunked transfer encoding!

    ### Error codes
    Icecast reponds with valid HTTP Status codes, and a message, indicating what was wrong in case of error.
    @@ -78,6 +79,17 @@ In case of success it sends status code `200` with message `OK`. Below there is
    `500 Internal Server Error`
    : An internal Icecast error happened, there is nothing that the client can do about it.

    If anything goes wrong, the source client should show a helpful error message to the user, so that he knows what happened.
    Do __not__ shows generic messages like "An error has occured" or "Connection to Icecast failed" if it is possible to
    provide more details.
    For example, a good error message for `403 Mountpoint in use` would be:
    "Couldn't connect to Icecast, because the specified mountpoint is already in use."

    ## HTTP SOURCE based protocol
    Older Icecast servers prior to 2.4.0 used a custom HTTP method for source clients, called `SOURCE`.
    It is nearly equal to the above described PUT method, but doesn't has support for the `100-continue` header.
    It is nearly equal to the above described PUT method, but doesn't has support for the `100-continue` header.
    The SOURCE method is deprecated since 2.4.0 and should not be used anymore. It will propably be removed in a future version.

    ## Which method to use
    Since the old `SOURCE` method is deprecated, a client should try both, first `PUT` and then fall back to `SOURCE` if the `PUT` method doesn't work.
    In case of the `PUT` method being used with older Icecast versions that do not support it (< 2.4.0), Icecast will return an empty reply, this means, no status code or headers or body is sent.
  17. @ePirat ePirat revised this gist Nov 10, 2014. 2 changed files with 83 additions and 23 deletions.
    23 changes: 0 additions & 23 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -1,23 +0,0 @@
    # Icecast protocol specification

    ## What is the Icecast protocol?
    When speaking of the Icecast protocol here, actually it's just the HTTP protocol, and here we will explain futher how
    source clients need to send data to Icecast.

    ## HTTP PUT based protocol
    Since Icecast version 2.4.0 there is support for the standard [HTTP `PUT`](http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6) method.
    The mountpoint to which to send the data is specified by the URL path.

    ### Authentication
    The authentication is done using [HTTP Basic auth](http://tools.ietf.org/html/rfc2617#section-2).
    To quickly sum it up how it works:
    The client needs to send the `Authorization` header to Icecast, with a value of `Basic` (for basic authentication)
    followed by a whitespace and then the username and password separated by a colon `:` encoded as Base64.

    ### Specifying mountpoint informations
    The mountpoint itself is specified as the path part of the URL.
    Additional mountpoint information can be set using specific (non-standard) HTTP headers:

    ice-public
    : For a mountpoint that doesn't has `<public>` configured, this influences if the mountpoint shoult be advertised to a YP directory or not.

    83 changes: 83 additions & 0 deletions spec.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,83 @@
    # Icecast protocol specification

    ## What is the Icecast protocol?
    When speaking of the Icecast protocol here, actually it's just the HTTP protocol, and here we will explain futher how
    source clients need to send data to Icecast.

    ## HTTP PUT based protocol
    Since Icecast version 2.4.0 there is support for the standard HTTP [`PUT`](http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6) method.
    The mountpoint to which to send the data is specified by the URL path.

    ### Authentication
    The authentication is done using [HTTP Basic auth](http://tools.ietf.org/html/rfc2617#section-2).
    To quickly sum it up how it works:
    The client needs to send the `Authorization` header to Icecast, with a value of `Basic` (for basic authentication)
    followed by a whitespace and then the username and password separated by a colon `:` encoded as Base64.

    ### Specifying mountpoint information
    The mountpoint itself is specified as the path part of the URL.
    Additional mountpoint information can be set using specific (non-standard) HTTP headers:

    ice-public
    : For a mountpoint that doesn't has `<public>` configured, this influences if the mountpoint shoult be advertised to a YP directory or not. Value can either be `0` (not public) or `1` (public).

    ice-name
    : For a mountpoint that doesn't has `<stream-name>` configure, this sets the name of the stream.

    ice-description
    : For a mountpoint that doesn't has `<stream-description>` configure, this sets the description of the stream.

    ice-url
    : For a mountpoint that doesn't has `<stream-url>` configure, this sets the URL to the Website of the stream. (This should _not_ be the Server or mountpoint URL)

    ice-genre
    : For a mountpoint that doesn't has `<genre>` configure, this sets the genre of the stream.

    ice-bitrate
    : This sets the bitrate of the stream.

    ice-audio-info
    : A Key-Value list of audio information about the stream, using `=` as separator between key and value and `;` as separator of the Key-Value pairs.
    Values must be URL-encoded if necessary.
    Example: `samplerate=44100;quality=10%2e0;channels=2`

    Content-Type
    : Indicates the content type of the stream, this must be set.

    ### Sending data
    Data is sent as usual in the body of the request, but it has to be sent at the right timing. This means if the source client sends data to Icecast that is already completely avaliable, it may not sent all the data right away, else Icecast will not be able to keep up. The source client is expected to sent the data as if it is live.

    ### Error codes
    Icecast reponds with valid HTTP Status codes, and a message, indicating what was wrong in case of error.
    In case of success it sends status code `200` with message `OK`. Below there is a full list of status codes and possible errors.

    `200 OK`
    : Everything ok

    `100 Continue`
    : This is sent in case a `Request: 100-continue` header was sent by the client and everything is ok. It indicates that the client can go on and send data.

    `401 You need to authenticate`
    : No auth information sent or credentials wrong.

    `403 Content-type not supported`
    : The supplied Content-Type is not supported by Icecast.

    `403 No Content-type given`
    : There was no Content-Type given. The source client is required to send a Content-Type.

    `403 internal format allocation problem`
    : There was a problem allocating the format handler, this is an internal Icecast problem.

    `403 too many sources connected`
    : The configured source client connection limit was reached and no more source clients can connect at the moment.

    `403 Mountpoint in use`
    : The mountpoint the client tried to connect too is already used by another client.

    `500 Internal Server Error`
    : An internal Icecast error happened, there is nothing that the client can do about it.

    ## HTTP SOURCE based protocol
    Older Icecast servers prior to 2.4.0 used a custom HTTP method for source clients, called `SOURCE`.
    It is nearly equal to the above described PUT method, but doesn't has support for the `100-continue` header.
  18. @ePirat ePirat created this gist Nov 10, 2014.
    23 changes: 23 additions & 0 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,23 @@
    # Icecast protocol specification

    ## What is the Icecast protocol?
    When speaking of the Icecast protocol here, actually it's just the HTTP protocol, and here we will explain futher how
    source clients need to send data to Icecast.

    ## HTTP PUT based protocol
    Since Icecast version 2.4.0 there is support for the standard [HTTP `PUT`](http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6) method.
    The mountpoint to which to send the data is specified by the URL path.

    ### Authentication
    The authentication is done using [HTTP Basic auth](http://tools.ietf.org/html/rfc2617#section-2).
    To quickly sum it up how it works:
    The client needs to send the `Authorization` header to Icecast, with a value of `Basic` (for basic authentication)
    followed by a whitespace and then the username and password separated by a colon `:` encoded as Base64.

    ### Specifying mountpoint informations
    The mountpoint itself is specified as the path part of the URL.
    Additional mountpoint information can be set using specific (non-standard) HTTP headers:

    ice-public
    : For a mountpoint that doesn't has `<public>` configured, this influences if the mountpoint shoult be advertised to a YP directory or not.