@theoplayer/react-native-ui
Version:
A React Native UI for @theoplayer/react-native
138 lines • 5.12 kB
JavaScript
import { findMediaTrackByUid, PlayerEventType } from 'react-native-theoplayer';
import React, { PureComponent, useContext } from 'react';
import { Platform } from 'react-native';
import { PlayerContext } from '../util/PlayerContext';
import { MenuView } from './common/MenuView';
import { ScrollableMenu } from './common/ScrollableMenu';
import { MenuRadioButton } from './common/MenuRadioButton';
import { SubMenuWithButton } from './common/SubMenuWithButton';
import { calculateQualityLabelParams } from '../util/TrackUtils';
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
/**
* A button component that opens a video quality selection menu for the `react-native-theoplayer` UI.
*/
export const QualitySubMenu = props => {
const {
menuStyle
} = props;
const {
player,
locale
} = useContext(PlayerContext);
if (Platform.OS === 'ios') {
return /*#__PURE__*/_jsx(_Fragment, {});
}
const createMenu = () => {
return /*#__PURE__*/_jsx(QualitySelectionView, {
style: menuStyle
});
};
let selectedQualityLabel = locale.automaticQualitySelectionLabel;
if (player.targetVideoQuality !== undefined) {
let id;
if (typeof player.targetVideoQuality === 'number') {
id = player.targetVideoQuality;
} else {
id = player.targetVideoQuality.length > 0 ? player.targetVideoQuality[0] : undefined;
}
const selectedTrack = player.videoTracks.find(track => track.uid === player.selectedVideoTrack);
const selectedQuality = selectedTrack !== undefined ? selectedTrack.qualities.find(quality => quality.uid === id) : undefined;
if (selectedQuality !== undefined) {
selectedQualityLabel = locale.qualityLabel(calculateQualityLabelParams(selectedQuality));
}
}
return /*#__PURE__*/_jsx(SubMenuWithButton, {
menuConstructor: createMenu,
label: locale.qualityTitle,
preview: selectedQualityLabel
});
};
export class QualitySelectionView extends PureComponent {
constructor(props) {
super(props);
this.state = {
videoTracks: [],
selectedVideoTrack: undefined,
targetVideoTrackQuality: undefined
};
}
componentDidMount() {
const player = this.context.player;
player.addEventListener(PlayerEventType.MEDIA_TRACK_LIST, this.onTrackListChanged);
this.setState({
videoTracks: player.videoTracks,
selectedVideoTrack: player.selectedVideoTrack,
targetVideoTrackQuality: player.targetVideoQuality
});
}
componentWillUnmount() {
const player = this.context.player;
player.removeEventListener(PlayerEventType.MEDIA_TRACK_LIST, this.onTrackListChanged);
}
onTrackListChanged = () => {
const player = this.context.player;
this.setState({
videoTracks: player.videoTracks,
selectedVideoTrack: player.selectedVideoTrack,
targetVideoTrackQuality: player.targetVideoQuality
});
};
selectTargetVideoQuality = qualityIndex => {
const {
videoTracks,
selectedVideoTrack
} = this.state;
if (!videoTracks || !selectedVideoTrack) {
return;
}
const videoTrack = videoTracks.find(track => track.uid === selectedVideoTrack);
const qualities = videoTrack?.qualities;
if (!qualities) {
return;
}
let uid = undefined;
if (qualityIndex !== undefined && qualityIndex > 0) {
// The first quality in the list is "auto". The rest are selectable qualities.
uid = qualities[qualityIndex - 1].uid;
}
const player = this.context.player;
player.targetVideoQuality = uid;
this.setState({
targetVideoTrackQuality: uid
});
};
render() {
const {
style
} = this.props;
const {
videoTracks,
selectedVideoTrack,
targetVideoTrackQuality
} = this.state;
const availableVideoQualities = findMediaTrackByUid(videoTracks, selectedVideoTrack)?.qualities || [];
availableVideoQualities.sort((q1, q2) => q2.bandwidth - q1.bandwidth);
let selectedTarget;
if (targetVideoTrackQuality === undefined || typeof targetVideoTrackQuality === 'number') {
selectedTarget = targetVideoTrackQuality;
} else {
selectedTarget = targetVideoTrackQuality.length > 0 ? targetVideoTrackQuality[0] : undefined;
}
return /*#__PURE__*/_jsx(PlayerContext.Consumer, {
children: context => /*#__PURE__*/_jsx(MenuView, {
style: style,
menu: /*#__PURE__*/_jsx(ScrollableMenu, {
title: context.locale.qualityTitle,
items: [undefined, ...availableVideoQualities].map((quality, id) => /*#__PURE__*/_jsx(MenuRadioButton, {
label: quality === undefined ? context.locale.automaticQualitySelectionLabel : context.locale.qualityLabelExtended(calculateQualityLabelParams(quality)),
uid: id,
onSelect: this.selectTargetVideoQuality,
selected: quality === undefined && selectedTarget === undefined || quality !== undefined && quality.uid === selectedTarget
}, id))
})
})
});
}
}
QualitySelectionView.contextType = PlayerContext;
//# sourceMappingURL=QualitySubMenu.js.map