# How to programmatically detect video track quality changes

This article describes how you can use the API to detect video track quality changes.

The VideoTrack API, which is a sub-API of the MediaTrack API, can be used to implement this functionality. Implementing this functionality is a common use-case for developers who want to build their own UI to visualize the available video track qualities.

## SDKs

| Web SDK | Android SDK | iOS SDK | tvOS SDK | Android TV SDK | Chromecast SDK |
| ------- | ----------- | ------- | -------- | -------------- | -------------- |
| Yes     | Yes         | Yes     | Yes      | Yes            | Yes            |

## Code examples

The code examples below how to implement the detection of video track qualities across SDK.

##### Web SDK

The Web SDK leverages the [MediaTrack API](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/v10/api-reference/web/interfaces/MediaTrack).

```js
// detect video tracks being added to the player
player.videoTracks.addEventListener('addtrack', function (e0) {
  // detect quality changes of a track
  e0.track.addEventListener('activequalitychanged', function (e1) {
    console.log('activequalitychanged event detected!', e1);
  });
});
```

##### Android (TV) SDK

The Android SDK leverages the [MediaTrack API](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/v10/api-reference/android/com/theoplayer/android/api/player/track/mediatrack/MediaTrackList).

```java
EventListener<AddTrackEvent> handleAddTrackEvent = new EventListener<AddTrackEvent>() {
    EventListener<ActiveQualityChangedEvent> handleActiveQualityChangedEvent = new EventListener<ActiveQualityChangedEvent>() {
        @Override
        public void handleEvent(ActiveQualityChangedEvent activeQualityChangedEvent) {
            System.out.println("activequalitychanged event detected! " + activeQualityChangedEvent.getQuality().toString());
        }
    };
    @Override
    public void handleEvent(AddTrackEvent addTrackEvent) {
        addTrackEvent.getTrack().addEventListener(VideoTrackEventTypes.ACTIVEQUALITYCHANGEDEVENT, handleActiveQualityChangedEvent);
    }
};
tpv.getPlayer().getVideoTracks().addEventListener(VideoTrackListEventTypes.ADDTRACK, handleAddTrackEvent);
```

##### iOS (/tvOS) SDK

```swift
player.videoTracks.addEventListener(type: VideoTrackListEventTypes.ADD_TRACK, listener: { addTrackEvent in
    guard let videoTrack = addTrackEvent.track as? VideoTrack else { return }
    videoTrack.addEventListener(type: MediaTrackEventTypes.ACTIVE_QUALITY_CHANGED, listener: { qualityChangeEvent in
        let quality = qualityChangeEvent.quality
        var msg = "Quality changed: bandwidth = \(quality.bandwidth)"
        if let videoQuality = quality as? VideoQuality {
            msg.append(", width = \(videoQuality.width), height = \(videoQuality.height)")
        }
        print(msg)
    })
})
```

## Remarks

* A related article on building a Chromeless UI is located at [How to build a Chromeless UI](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/v10/how-to-guides/ui/how-to-build-chromeless-ui.md).

## Related articles

* [How to programmatically detect audio tracks](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/v10/how-to-guides/mediatrack/how-to-detect-audio-tracks.md)
* [How to programmatically detect video track quality changes](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/v10/how-to-guides/mediatrack/how-to-detect-video-track-quality-changes.md)
* [How to programmatically enable or disable audio tracks](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/v10/how-to-guides/mediatrack/how-to-enable-disable-audio-tracks.md)
* [How to programmatically select a video track quality](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/v10/how-to-guides/mediatrack/how-to-select-video-track-quality.md)
