feat(item): use of track selector component

This commit is contained in:
Thibault Nocchi 2021-01-08 16:18:50 +01:00
parent c51ecc49b3
commit e588c50863

View File

@ -157,16 +157,7 @@
</v-row>
</v-col>
</v-row>
<div
v-if="
item &&
((item.MediaSources && item.MediaSources.length > 1) ||
videoTracks.length > 0 ||
audioTracks.length > 0 ||
subtitleTracks.length > 0)
"
class="mt-2"
>
<div v-if="item && item.MediaSources" class="mt-2">
<v-row v-if="item.MediaSources.length > 1" align="center">
<v-col
cols="12"
@ -200,7 +191,7 @@
</v-select>
</v-col>
</v-row>
<v-row v-if="videoTracks.length > 0" align="center">
<v-row align="center">
<v-col
cols="12"
sm="2"
@ -213,28 +204,15 @@
<label class="text--secondary">{{ $t('video') }}</label>
</v-col>
<v-col cols="12" sm="10">
<v-select
v-model="currentVideoTrack"
:items="getItemizedSelect(videoTracks)"
:disabled="videoTracks.length <= 1"
outlined
filled
flat
dense
single-line
hide-details
class="text-truncate"
>
<template slot="selection" slot-scope="{ item: i }">
{{ i.value.DisplayTitle }}
</template>
<template slot="item" slot-scope="{ item: i }">
{{ i.value.DisplayTitle }}
</template>
</v-select>
<track-selector
:item="item"
:media-source-index="currentSourceIndex"
:type="'Video'"
@input="currentVideoTrack = $event"
></track-selector>
</v-col>
</v-row>
<v-row v-if="audioTracks.length > 0" align="center">
<v-row align="center">
<v-col
cols="12"
sm="2"
@ -247,40 +225,12 @@
<label class="text--secondary">{{ $t('audio') }}</label>
</v-col>
<v-col cols="12" sm="10">
<v-select
v-if="audioTracks.length > 0"
v-model="currentAudioTrack"
:items="getItemizedSelect(audioTracks)"
:disabled="audioTracks.length <= 1"
outlined
filled
flat
dense
single-line
hide-details
class="text-truncate"
>
<template slot="selection" slot-scope="{ item: i }">
{{ i.value.DisplayTitle }}
</template>
<template slot="item" slot-scope="{ item: i, on, attrs }">
<v-list-item v-bind="attrs" two-line v-on="on">
<v-list-item-avatar>
<v-icon
v-text="getSurroundIcon(i.value.ChannelLayout)"
></v-icon>
</v-list-item-avatar>
<v-list-item-content>
<v-list-item-title>{{
i.value.DisplayTitle
}}</v-list-item-title>
<v-list-item-subtitle>
{{ getLanguageName(i.value.Language) }}
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</template>
</v-select>
<track-selector
:item="item"
:media-source-index="currentSourceIndex"
:type="'Audio'"
@input="currentAudioTrack = $event"
></track-selector>
</v-col>
</v-row>
<v-row align="center">
@ -296,40 +246,12 @@
<label class="text--secondary">{{ $t('subtitles') }}</label>
</v-col>
<v-col cols="12" sm="10">
<v-select
v-model="currentSubtitleTrack"
:items="getItemizedSelect(subtitleTracks)"
:placeholder="
subtitleTracks.length === 0
? $t('noSubtitleAvailable')
: $t('noSubtitleSelected')
"
:disabled="subtitleTracks.length === 0"
clearable
outlined
filled
flat
dense
single-line
hide-details
class="text-truncate"
>
<template slot="selection" slot-scope="{ item: i }">
{{ i.value.DisplayTitle }}
</template>
<template slot="item" slot-scope="{ item: i, on, attrs }">
<v-list-item v-bind="attrs" two-line v-on="on">
<v-list-item-content>
<v-list-item-title>{{
i.value.DisplayTitle
}}</v-list-item-title>
<v-list-item-subtitle>
{{ getLanguageName(i.value.Language) }}
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</template>
</v-select>
<track-selector
:item="item"
:media-source-index="currentSourceIndex"
:type="'Subtitle'"
@input="currentSubtitleTrack = $event"
></track-selector>
</v-col>
</v-row>
</div>
@ -382,20 +304,18 @@
<script lang="ts">
import Vue from 'vue';
import { mapActions } from 'vuex';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment -- Temporary module while waiting for fixes to language names on the server
// @ts-ignore
import langs from 'langs';
import {
BaseItemDto,
BaseItemPerson,
MediaSourceInfo,
MediaStream
MediaSourceInfo
} from '@jellyfin/client-axios';
import imageHelper from '~/mixins/imageHelper';
import formsHelper from '~/mixins/formsHelper';
import itemHelper from '~/mixins/itemHelper';
import TrackSelector from '~/components/Item/TrackSelector.vue';
export default Vue.extend({
components: { TrackSelector },
mixins: [imageHelper, formsHelper, itemHelper],
async asyncData({ params, $api, $auth }) {
const item = (
@ -413,63 +333,14 @@ export default Vue.extend({
}
let currentSource: MediaSourceInfo = {};
let videoTracks: MediaStream[] = [];
let currentVideoTrack: MediaStream = {};
let audioTracks: MediaStream[] = [];
let currentAudioTrack: MediaStream = {};
let subtitleTracks: MediaStream[] = [];
let currentSubtitleTrack: MediaStream = {};
if (item.MediaSources && item.MediaSources.length > 0) {
if (item.MediaSources && item.MediaSources.length > 0)
currentSource = item.MediaSources[0];
// Filter the streams to get each type of track
if (currentSource.MediaStreams) {
videoTracks = currentSource.MediaStreams.filter(
(stream: MediaStream) => {
return stream.Type === 'Video';
}
);
audioTracks = currentSource.MediaStreams.filter(
(stream: MediaStream) => {
return stream.Type === 'Audio';
}
);
subtitleTracks = currentSource.MediaStreams.filter(
(stream: MediaStream) => {
return stream.Type === 'Subtitle';
}
);
// Set default tracks
if (videoTracks.length > 0) {
currentVideoTrack = videoTracks[0];
}
if (audioTracks.length > 0 && currentSource.DefaultAudioStreamIndex) {
currentAudioTrack =
audioTracks[currentSource.DefaultAudioStreamIndex - 1];
} else if (audioTracks.length > 0) {
currentAudioTrack = audioTracks[0];
}
if (
subtitleTracks.length > 0 &&
currentSource.DefaultSubtitleStreamIndex
) {
currentSubtitleTrack =
subtitleTracks[currentSource.DefaultSubtitleStreamIndex - 1];
}
}
}
return {
item,
crew,
currentSource,
videoTracks,
currentVideoTrack,
audioTracks,
currentAudioTrack,
subtitleTracks,
currentSubtitleTrack
currentSource
};
},
data() {
@ -479,12 +350,9 @@ export default Vue.extend({
parentItem: {} as BaseItemDto,
backdropImageSource: '',
currentSource: {} as MediaSourceInfo,
videoTracks: [] as MediaStream[],
currentVideoTrack: {} as MediaStream,
audioTracks: [] as MediaStream[],
currentAudioTrack: {} as MediaStream,
subtitleTracks: [] as MediaStream[],
currentSubtitleTrack: {} as MediaStream
currentVideoTrack: undefined as number | undefined,
currentAudioTrack: undefined as number | undefined,
currentSubtitleTrack: undefined as number | undefined
};
},
head() {
@ -493,6 +361,13 @@ export default Vue.extend({
};
},
computed: {
currentSourceIndex: {
get(): number | undefined {
return this.item.MediaSources?.findIndex(
(source) => source === this.currentSource
);
}
},
isPlayable: {
get(): boolean {
// TODO: Move this to a mixin
@ -545,27 +420,7 @@ export default Vue.extend({
methods: {
...mapActions('playbackManager', ['play']),
...mapActions('page', ['setPageTitle', 'setAppBarOpacity']),
...mapActions('backdrop', ['setBackdrop', 'clearBackdrop']),
getLanguageName(code?: string): string {
if (!code) {
return this.$t('undefined');
}
return langs.where('2B', code).name;
},
getSurroundIcon(layout: string): string {
switch (layout) {
case '2.0':
return 'mdi-surround-sound-2-0';
case '3.1':
return 'mdi-surround-sound-3-1';
case '5.1':
return 'mdi-surround-sound-5-1';
case '7.1':
return 'mdi-surround-sound-7-1';
default:
return 'mdi-surround-sound';
}
}
...mapActions('backdrop', ['setBackdrop', 'clearBackdrop'])
}
});
</script>