tcacciatore
tcacciatore

Reputation: 493

Detect when AvPlayer switch bit rate

In my application, I use the AVPlayer to read some streams (m3u8 file), with HLS protocol. I need to know how many times, during a streaming session, the client switches bitrate.

Let's assume the client's bandwidth is increasing. So the client will switch to a higher bitrate segment. Can the AVPlayer detect this switch ?

Thanks.

Upvotes: 12

Views: 8300

Answers (2)

Nahuel Roldan
Nahuel Roldan

Reputation: 673

BoardProgrammer's solution works great! In my case, I needed the indicated bitrate to detect when the content quality switched from SD to HD. Here is the Swift 3 version.

// Add observer.
NotificationCenter.default.addObserver(self,
                                           selector: #selector(handleAVPlayerAccess),

                                           name: NSNotification.Name.AVPlayerItemNewAccessLogEntry,
                                           object: nil)

// Handle notification.
func handleAVPlayerAccess(notification: Notification) {

    guard let playerItem = notification.object as? AVPlayerItem,
        let lastEvent = playerItem.accessLog()?.events.last else {
        return
    }

    let indicatedBitrate = lastEvent.indicatedBitrate

    // Use bitrate to determine bandwidth decrease or increase.
}

Upvotes: 9

BoardProgrammer
BoardProgrammer

Reputation: 185

I have had a similar problem recently. The solution felt a bit hacky but it worked as far as I saw. First I set up an observer for new Access Log notifications:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(handleAVPlayerAccess:)
                                             name:AVPlayerItemNewAccessLogEntryNotification
                                           object:nil];

Which calls this function. It can probably be optimised but here is the basic idea:

- (void)handleAVPlayerAccess:(NSNotification *)notif {
    AVPlayerItemAccessLog *accessLog = [((AVPlayerItem *)notif.object) accessLog];
    AVPlayerItemAccessLogEvent *lastEvent = accessLog.events.lastObject;
    float lastEventNumber = lastEvent.indicatedBitrate;
    if (lastEventNumber != self.lastBitRate) {
        //Here is where you can increment a variable to keep track of the number of times you switch your bit rate.
        NSLog(@"Switch indicatedBitrate from: %f to: %f", self.lastBitRate, lastEventNumber);
        self.lastBitRate = lastEventNumber;
    }
}

Every time there is a new entry to the access log, it checks the last indicated bitrate from the most recent entry (the lastObject in the access log for the player item). It compares this indicated bitrate with a property that stored the the bitrate from that last change.

Upvotes: 17

Related Questions