pocket-casts-ios: Incorrect durations: discussion

We’ve gotten several reports of episodes that report an incorrect duration and stop playing before they should. I’d love to either:

  1. Find a way to patch this up on our end (so even MP3s with invalid headers/frames play for their intended duration); or
  2. Document how HEs can check if an episode has incorrect headers/frames, and create a predef that users can send to podcast hosts that helps the hosts fix the issue on their end

The common thread seems to be that when streaming, the episode has the correct duration, but when it gets downloaded the duration shortens. This makes the episode stop before it “should”. @rustyshelf has mentioned this being a discrepancy between AVPlayer (used for streaming) and AVAudioEngine (used for downloaded files) based on incorrect metadata/headers in the MP3.

My research leads me to think that these episodes are reporting the wrong number of audio frames though they are reporting the correct audio size/bitrate. I don’t know if this is something we can or should fix on our own, or how to help podcast hosts realize the problem is with their encoding.

Here’s my research:


Example 1

Here’s an example episode from Ruthless (hosted by Simplecast). The expected duration is 01:21:47 (4907 seconds) but after download the app shows 39:29 (2369 seconds).

Here’s an MP3 I downloaded for that episode. This is what afinfo shows:

$ afinfo ruthless-5-4-22.mp3
File:           ruthless-5-4-22.mp3
File type ID:   MPG3
Num Tracks:     1
----
Data format:     2 ch,  44100 Hz, .mp3 (0x00000000) 0 bits/channel, 0 bytes/packet, 1152 frames/packet, 0 bytes/frame
                no channel layout.
estimated duration: 4907.206500 sec
audio bytes: 157030608
audio packets: 187854
bit rate: 256000 bits per second
packet size upper bound: 1052
maximum packet size: 836
audio data file offset: 630
optimized
audio 104464252 valid frames + 528 priming + 2036 remainder = 104466816
Loudness Info:
    sound check info                 :
        sc ave perceived power coeff     : "1441 1441 "
        sc max perceived power coeff     : "182074 182074 "
        sc peak amplitude msec           : "80195 80195 "
        sc max perceived power msec      : "1201293 1201293 "
        sc peak amplitude                : "32766 32766 "


sound check volume normalization gain: -2.00 dB
----

It reports estimated duration: 4907.206500 sec (the expected value) which I can also calculate based on reported audio bytes and bit rate:

157030608 bytes * 8 bits per byte / 256000 bits per second = 4907.2065 seconds

But if you calculate duration from the number of audio valid frames and sample rate you get a different duration:

104464252 valid frames / 44100 Hz (frames per second) = 2369 seconds

This matches the 39:29 duration we see after the episode ends. In our code in at least one place, this is how we calculate episode duration.


Example 2

The podcast Parenting Hell (hosted by Podbean) has come up a couple times. It seems to be a problem with their dynamic ads, which I get served from the UK but not from the US:

Like Example 1, the afinfo shows the correct estimated duration, which can be calculated from audio bytes and bit rate. But interestingly, both episodes have the same number of audio valid frames. Since the UK version is longer, it should have more frames. And indeed, when this episode is downloaded in-app (from the UK) and played, it shows the duration 51:55 (3115 seconds), the same as the US episode.

So in this case, it seems the host is not adjusting the frame count when dynamic ads are inserted.


Related Slack threads:

  • p1652210212805519-slack-C02A333D8LQ
  • p1652181437367739-slack-C02A333D8LQ
  • p1646435740232409-slack-C02A333D8LQ

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Comments: 27 (11 by maintainers)

Most upvoted comments

@rviljoen Sure! I’m having trouble uploading the file here, but can you see if you’re able to download it right from this source URL?