Audio Stream output metadata is incorrect.

Issue #793 resolved
Former user created an issue

I use BubbleUPnP to play my Serviio Media on my Android Tablet. When Audio is played by Bubble, it also displays the bitrate and sample rate provided by the Media Server.

When playing on-line audio streams in Bubble as provided by my Serviio Shoutcast plugin however, first problem is that the bitrate shows as 48kb/sec regardless of the original bitrate and the second problem is that the samplerate shows as 48kHz if the original stream has a sample rate not equal to 44.1kHz regardless of the original sample rate, and the third problem is that samplerate shows nothing at all if the sample rate of the original stream is 44.1.

On investigation, the Bubble log shows that these errors come from Serviio. Here is a sample Bubble log entry showing the bitrate of a 32KB stream as 48000 with no samplerate even though it is 44.1KHz.

#!

[playItem        ] INFO     - 19:00:33.520 - UPnPAVRenderer              : UPnPAVRenderer.playItem: SetAVTransportURI metadata: <DIDL-Lite xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dlna="urn:schemas-dlna-org:metadata-1-0/" xmlns:sec="http://www.sec.co.kr/"><item id="A_OF^FOL_FD206$OI1000002060005410" parentID="A_OF^FOL_FD206" restricted="1"><upnp:class>object.item.audioItem.musicTrack</upnp:class><dc:title>(32KB) Radio ZU Live - Pop (7646)</dc:title><dc:creator>Unknown Artist</dc:creator><upnp:artist>Unknown Artist</upnp:artist><dc:date>2014-07-04</dc:date><upnp:album>Unknown Album</upnp:album><res protocolInfo="http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=00;DLNA.ORG_CI=1;DLNA.ORG_FLAGS=8D500000000000000000000000000000" bitrate="48000" nrAudioChannels="2">http://192.168.1.10:8895/resource/1000002060005410/MEDIA_ITEM/MP3-0/ORIGINAL</res></item></DIDL-Lite>

After diagnosing this with Serviio, it turns out that the generic profile for online streams contains the line, <Audio targetContainer="mp3" aBitrate="384" forceInheritance="true"> even though the maximum bit rate for mp3 is 320. When Serviio transcodes the stream, it actually transcodes at 320, however it reports 48000 to Bubble.

If the generic profile is changed to <Audio targetContainer="mp3" aBitrate="320" forceInheritance="true"> the transcoding is at 320 and the bitrate is also reported correctly as 320000. The bigger issue however is why the bitrate is being changed and not left at its original bitrate. By removing the aBitrate parameter the line becomes <Audio targetContainer="mp3" forceInheritance="true"> and the original bitrate is retained and reported to bubble correctly for both remuxed original mp3 and transcoded aac streams. If the bitrate is required for other codecs the profile should be split.

The second problem, results from Serviio arbitrarily adding the parameter -ar 48000 to the ffmpeg transcoding command when the samplerate of the original is not 44.1, rather than specifying the samplerate in the original eg: -ar 22050, and not specifying -ar 44100 when the original is 44.1KHz.

#!

ffmpeg.exe -analyzeduration 10000000 -threads 8 -i http://194.232.200.156:8000 -y -threads 8 -b:a 64k -id3v2_version 3 -ar 48000 -ac 2 -f mp3 pipe: 

Again this seems unwarranted because when I remove that arbitrary parameter and add the original sample rate (using my fffmpeg intercept) the original sample rates play correctly. However the sample rate continues to be reported to Bubble as 48000 Hz, so Serviio is not reporting the value from the actual output stream but is rather arbitrarily plugging the value based on the addition of -ar 48000.

Similarly with problem #3, the failure to report the samplerate when it is 44.1 is again an example of Serviio not reporting the value of the actual output stream.

In summary, the fix request is to 1) remove aBitrate="384" from the mp3 transcode in the generic profile so the original bitrate is retained. 2) always add -ar using the original sample rate rather than forcing 48000 or skipping 44100 so that ffmpeg retains the original samplerate (note that if -ar is not specified ffmpeg may alter the bitrate) and 3) to report the actual samplerate of the output stream.

Comments (15)

  1. Petr Nejedly repo owner

    1 - will fix it to 320. I think some renderers are having problems with lower bitrates, that's why it's often forced to 384 or similar. 2 - Some time ago it's been fixed to behave like this (apparently either due to renderers not playing sub-44 streams correctly or FFmpeg failing the transcode in some cases). The behaviour is: If frequency is less than 44100, use 48000 as the tagret frequency. Otherwise don't pass -ar so that ffmpeg keeps the original one. 3 - True, it doesn't send the frequency over for transcoded files that don't change their target frequency (see 2). Will fix this.

  2. Former user Account Deleted

    Thanks for your prompt response.

    I think those were the best approaches in earlier releases but in both cases, now that Serviio has matured and stabilized and many ffmpeg issues resolved, those problems (if any still remain) should now be handled in the appropriate profiles.

    When you force aBitrate=320 in the generic profile, I have to remove it by overriding it in each of my device profiles and all of the mediabrowser and serviigo application profiles in order to get the correct original bitrates used in the ffmpeg -b:a command parameter. To avoid this I have simply removed aBitrate=320 from the generic profile and will add it to any device profile that requires it, as believe you should do as well. All my streams are now playing fine at their original rates.

    Similarly when you force -ar 48000 in the ffmpeg command for all devices, I have no way of removing it to restore the original sample rate for devices which can play all sample rates, except by intercepting it in my ffmpeg.bat and stripping it before sending the command on to Serviio, however normal users cannot override it.

    This I have done to remove any -ar 48000 so the original samplerates will always be used, and I will add aSamplerate=44100 to any device profiles unable to play lower rates, as I believe you should do as well. Note that I chose 44100 rather than 48000 because 44.1(and its subsets) is the defacto rate used by most on-line audio streams, and so any 44.1s will remain as is, and any 48kHz (very few) and any less than 44.1 will convert to 44.1. All my streams are playing correctly at their original sample rate.

    With these fixes, my on-line audio by default plays in its original form, and I can fix any device that cannot. I believe Serviio should do the same, and when you send the correct frequency for all streams, Serviio will also report these values.

  3. Petr Nejedly repo owner

    Why is it a problem of using the highest possible bitrate (320)? It should keep the quality high. E.g. if your original bitrate is 128 and you transcode it again using 128, surely the quality will be worse that going 128 -> 320.

    Similar with sample rate, is there actually any drawback of using 48k rather than (lets say) 22500?

    As you said, Serviio has matured, but that is due to it including all these fixes that were added over time.

  4. Former user Account Deleted

    Because I assume that when the bitrate and samplerate are unchanged for mp3 that it would just remux to mp3, whereas changing the bitrate and/or samplerate will cause conversion and the introduction of artifacts and reduced quality. Am I all wet?

  5. Petr Nejedly repo owner

    No, that's not how it works. I think FFmpeg would decode it to a raw format and then encode again.

  6. Former user Account Deleted

    Yes, I see that now based on the ffmpeg you generate. To avoid the transcoding (which means most mp3's) you would have to use -c:a copy if aBitrate and/or aSamplerate are either not specified in the profile or do match the metadata values of the source mp3.

    Since I can play files at any rates and prefer not to transcode, I have faked this in the generic profile by putting mp3 in a separate section with aSamplerate="0" which I use as a flag and replace with -c:a copy in my ffmpeg intercept. Now all my mp3's play in their original form without transcoding. Then by removing aBitrate="384" in the remaining section, and removing any -ar 48000 you generate in my ffmpeg intercept, the other codecs transcode at their original bit and sample rates.

    This also allows me to specify aBitrate="320" and/or aSamplerate="44100" in any device profile that cannot handle lower bitrates, however I have been thru the bitbucket and forums and can find no documented problems except my 421 which interestingly you declined because most renderers would play the native mp3's.

    I sill recommend that you support original streams as much as possible by default and handle exceptions in individual profiles.

  7. Petr Nejedly repo owner

    *looking at the code, it should use c:a copy when

    • the container is the same
    • there is no sample rate in the transcoding config or it's not being changed by the transcode
  8. Former user Account Deleted

    Super but its not working, perhaps because there is a 3rd condition to satisfy,namely

    3) there is no bitrate in the transcoding config or its not being changed by the transcode.

    Since the current profile contains aBitrate="384" these conditions will not satisfy and transcode will occur:

    I have done the following test satisfy the conditions:

    1) generic profile with aBitrate removed

    #!
    
            <OnlineTranscoding>
    
                <Audio targetContainer="mp3" forceInheritance="true">
                    <Matches container="flv"/>
                    <Matches container="asf"/>
                    <Matches container="rtp"/>
                    <Matches container="rtsp"/>
                    <Matches container="mp4"/>          
                    <Matches container="mp3"/>
                </Audio>
            </OnlineTranscoding>
    

    2) mp3 stream with bitrate 128 and samplerate 44.1

    #!
    
    C:\Users\John>ffmpeg -i http://2073.live.streamtheworld.com:443/CBC_R2_TOR_H_SC
    ffmpeg version N-62669-g443936d Copyright (c) 2000-2014 the FFmpeg developers
      built on Apr 23 2014 22:01:58 with gcc 4.8.2 (GCC)
      configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-a
    isynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --ena
    le-iconv --enable-libass --enable-libbluray --enable-libcaca --enable-libfreety
    e --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --en
    ble-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-
    ibopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libs
    eex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-a
    cenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwav
    ack --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enabl
    -decklink --enable-zlib
      libavutil      52. 78.100 / 52. 78.100
      libavcodec     55. 59.100 / 55. 59.100
      libavformat    55. 37.101 / 55. 37.101
      libavdevice    55. 13.100 / 55. 13.100
      libavfilter     4.  4.100 /  4.  4.100
      libswscale      2.  6.100 /  2.  6.100
      libswresample   0. 18.100 /  0. 18.100
      libpostproc    52.  3.100 / 52.  3.100
    [mp3 @ 00347ce0] Estimating duration from bitrate, this may be inaccurate
    Input #0, mp3, from 'http://2073.live.streamtheworld.com:443/CBC_R2_TOR_H_SC':
      Duration: 34:43:20.00, start: 0.000000, bitrate: 128 kb/s
        Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16p, 128 kb/s
    At least one output file must be specified
    

    FFmpeg command should be -c:a copy

    actual command per the log is:

    #!
    
    2014-07-07 20:21:43,298 DEBUG [AudioDeliveryEngine] Retrieving resource information for item 1000002070001453, format MP3 and profile Flash player
    2014-07-07 20:21:43,299 DEBUG [AbstractTranscodingDeliveryEngine] Getting media info for transcoded version of file http://2073.live.streamtheworld.com:443/CBC_R2_TOR_H_SC
    2014-07-07 20:21:43,299 DEBUG [AudioDeliveryEngine] Found Format profile for transcoded file http://2073.live.streamtheworld.com:443/CBC_R2_TOR_H_SC: MP3
    2014-07-07 20:21:43,302 DEBUG [AudioDeliveryEngine] Delivering item '1000002070001453' for client 'Identifier=127.0.0.1, Profile=Flash player'
    2014-07-07 20:21:43,302 DEBUG [AudioDeliveryEngine] Delivering file 'http://2073.live.streamtheworld.com:443/CBC_R2_TOR_H_SC' using transcoding
    2014-07-07 20:21:43,302 DEBUG [AbstractTranscodingDeliveryEngine] No suitable transcoding job exists yet, start one for client 'Identifier=127.0.0.1, Profile=Flash player'
    2014-07-07 20:21:43,303 DEBUG [FFMPEGWrapper] Invoking FFmpeg to transcode audio file: http://2073.live.streamtheworld.com:443/CBC_R2_TOR_H_SC
    2014-07-07 20:21:43,303 DEBUG [ProcessExecutor] Starting C:\Program Files\Serviio\lib\ffdump.bat -analyzeduration 10000000 -threads 8 -i http://2073.live.streamtheworld.com:443/CBC_R2_TOR_H_SC -y -threads 8 -b:a 128k -id3v2_version 3 -ac 2 -f mp3 pipe:
    2
    

    Thanks for sticking with this!

  9. Petr Nejedly repo owner

    both, audio streams in a video files and audio files should now use -c:a copy when codec / frequency and bitrate match

  10. Log in to comment