skip to Main Content

I’m working on a project where I have an instance of AVPlayer capable of playing different audio content that I retrieve from a backend, from podcast to music and streamings. Every content has two types of urls: one with mp3 and another with a m3u8 file. All the mp3 files work good. However some m3u8 files work fine and others don’t. In particular, those who don’t work cause the AVPlayer to crash with the error:

Error Domain=AVFoundationErrorDomain Code=-11819 "Cannot Complete Action"
UserInfo={NSLocalizedRecoverySuggestion=Try again later.,
NSLocalizedDescription=Cannot Complete Action.}

I don’t understand what the problem is. According to this answer it is a wrong Manifest file, which in my case is – for example – the following:

#EXTM3U
#EXT-X-MEDIA:TYPE=AUDIO,URI="_64/index.m3u8",GROUP-ID="2@48000-64000",NAME="AAC  64",DEFAULT=NO,AUTOSELECT=NO
#EXT-X-MEDIA:TYPE=AUDIO,URI="_80/index.m3u8",GROUP-ID="2@48000-80000",NAME="AAC 80",DEFAULT=NO,AUTOSELECT=NO
#EXT-X-MEDIA:TYPE=AUDIO,URI="_96/index.m3u8",GROUP-ID="2@48000-96000",NAME="AAC 96",DEFAULT=NO,AUTOSELECT=NO
#EXT-X-STREAM-INF:BANDWIDTH=133336,CODECS="mp4a.40.2",AUDIO="2@48000-96000"
_96/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=100641,CODECS="mp4a.40.2",AUDIO="2@48000-64000"
_64/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=116989,CODECS="mp4a.40.2",AUDIO="2@48000-80000"
_80/index.m3u8

On the Apple forum, I found this answer which says iOS 14+ is on fault. Unfortunately I cannot test with an iOS 13 physical device.

Do you have any suggestion?

Tested on Xcode 13.1 with iPhone 7plus with iOS 15.0.2.

2

Answers


  1. Chosen as BEST ANSWER

    Finally I found a solution for this issue. What worked for me was this. I believe the problem was that my manifest files were structured like the following:

    #EXT-X-MEDIA:TYPE=AUDIO,URI="_64/index.m3u8", GROUP-ID="1@48000-64000",NAME="Audio 64",DEFAULT=NO,AUTOSELECT=NO
    

    In particular they had DEFAULT=NO,AUTOSELECT=NO. Therefore before calling replaceCurrentItem I now do the following:

        let asset = AVAsset(url: url)
        let playerItem = AVPlayerItem(asset: asset)
        
        for characteristic in asset.availableMediaCharacteristicsWithMediaSelectionOptions {
            if let group = asset.mediaSelectionGroup(forMediaCharacteristic: AVMediaCharacteristic.audible) {
                if let option = group.options.first {
                    playerItem.select(option, in: group)
                }
            }
        }
    

    This makes all my HLS audio playable by the AVPlayer.


  2. I dont see version in your .m3u8. Try adding #EXT-X-VERSION:03 into your playlist. AVPlayer does need to have version included in playlist (Android EXO player does not need it). Here is example of playlist that might work:

        #EXTM3U
    #EXT-X-VERSION:03
    #EXT-X-MEDIA:TYPE=AUDIO,URI="_64/index.m3u8",GROUP-ID="2@48000-64000",NAME="AAC  64",DEFAULT=NO,AUTOSELECT=NO
    #EXT-X-MEDIA:TYPE=AUDIO,URI="_80/index.m3u8",GROUP-ID="2@48000-80000",NAME="AAC 80",DEFAULT=NO,AUTOSELECT=NO
    #EXT-X-MEDIA:TYPE=AUDIO,URI="_96/index.m3u8",GROUP-ID="2@48000-96000",NAME="AAC 96",DEFAULT=NO,AUTOSELECT=NO
    #EXT-X-STREAM-INF:BANDWIDTH=133336,CODECS="mp4a.40.2",AUDIO="2@48000-96000"
    _96/index.m3u8
    #EXT-X-STREAM-INF:BANDWIDTH=100641,CODECS="mp4a.40.2",AUDIO="2@48000-64000"
    _64/index.m3u8
    #EXT-X-STREAM-INF:BANDWIDTH=116989,CODECS="mp4a.40.2",AUDIO="2@48000-80000"
    _80/index.m3u8
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search