Router finished + slplayer fixes

This commit is contained in:
samcm 2017-12-24 01:24:24 +11:00
parent d53ce90745
commit 41e72204b4
16 changed files with 261 additions and 180 deletions

View File

@ -13,7 +13,7 @@
</v-navigation-drawer>
<v-toolbar app fixed>
<v-toolbar-side-icon @click="drawer = !drawer"></v-toolbar-side-icon>
<v-toolbar-title class="white--text">SyncLounge</v-toolbar-title>
<v-toolbar-title class="white--text"> SyncLounge </v-toolbar-title>
<v-spacer></v-spacer>
<v-toolbar-items>
<img class="ma-2" style="height:48px; width: 48px" v-bind:src="logo"/>
@ -162,7 +162,10 @@
},
itemCache: function () {
return this.$store.getters.getItemCache
},
},
libraryCache: function () {
return this.$store.getters.getLibraryCache
},
crumbs: function () {
if (this.$route.path.indexOf('browse') === -1) {
return []
@ -173,6 +176,13 @@
} catch (e) {
return 'Loading..'
}
}
const getLibrary = (id) => {
try {
return this.libraryCache[this.$route.params.machineIdentifier][id]
} catch (e) {
return 'Loading..'
}
}
let data = [{
text: 'Home',
@ -187,7 +197,7 @@
},
sectionId: () => {
return {
text: this.$route.params.sectionId,
text: getLibrary(this.$route.params.sectionId),
to: '/browse/' + this.$route.params.machineIdentifier + '/' + this.$route.params.sectionId
}
},
@ -197,7 +207,7 @@
to = '/browse/' + this.$route.params.machineIdentifier + '/' + this.$route.params.sectionId
+ '/tv/' + this.$route.params.grandparentKey + '/' + this.$route.params.parentKey
} else {
'/browse/' + this.$route.params.machineIdentifier + '/' + this.$route.params.sectionId
to = '/browse/' + this.$route.params.machineIdentifier + '/' + this.$route.params.sectionId
+ '/tv/' + this.$route.params.parentKey
}
return {
@ -283,7 +293,7 @@
mainStyle: function() {
if (this.$store.getters.getBackground != null){
return {
'background-image': 'url('+this.$store.getters.getBackground+')',
'background-image': 'url(' + this.$store.getters.getBackground + ')',
'background-repeat': 'no-repeat',
'background-size': 'cover',
'background-position': 'center'

View File

@ -19,7 +19,7 @@
<v-toolbar-item class="hidden-sm-and-down">
<img style="height:70%;width:auto" v-bind:src="logo"/>
</v-toolbar-item>
<v-toolbar-item class="hidden-sm-and-down" v-for="link in links" :href="link.href" :target="link.target">{{ link.title }}</v-toolbar-item>
<v-toolbar-item class="hidden-sm-and-down" v-for="link in links" :href="link.href" :key="link.href" :target="link.target">{{ link.title }}</v-toolbar-item>
</v-toolbar-items>
</v-toolbar>
</template>

View File

@ -1,5 +1,5 @@
<template>
<div>
<div ref="root">
<v-layout v-if="!contents" row >
<v-flex xs12 style="position:relative">
<v-progress-circular style="left: 50%; top:50%" v-bind:size="60" indeterminate class="amber--text"></v-progress-circular>
@ -8,7 +8,7 @@
<div v-if="contents">
<v-card v-if="contents" horizontal :img="getArtUrl" style="height: 80vh" class="darken-2 white--text">
<div style="background-color: rgba(0, 0, 0, 0.4); height: 100%">
<v-container style="background-color: rgba(0, 0, 0, 0.8)" fill-height>
<v-container style="background-color: rgba(0, 0, 0, 0.8); height: 100%" fluid>
<v-layout row wrap v-if="contents.type == 'episode'">
<v-flex md9 sm12 style="height 100%" class="mt-4 pa-1 pl-0">
<h3 style="font-weight:bold"> {{ contents.grandparentTitle }}</h3>
@ -33,17 +33,17 @@
</v-flex>
</v-flex>
</v-layout>
<v-layout justify-center align-start row wrap v-if="contents.type == 'movie'">
<v-flex md3 class="hidden-sm-and-down pa-4">
<v-layout justify-center align-center row wrap v-if="contents.type == 'movie'">
<v-flex md3 class="pa-4">
<v-layout row wrap>
<v-flex xs12>
<v-flex xs12 md12>
<v-card-media
:src="thumb"
height="30vh"
contain
></v-card-media>
</v-flex>
<v-flex xs12 class="text-xs-center">
<v-flex xs8 md12 class="text-xs-center hidden-sm-and-down ">
<div v-if="playable">
<v-btn block v-if="playable && contents.Media.length == 1 && (contents.viewOffset == 0 || !contents.viewOffset)" v-on:click.native="playMedia(contents)" class="primary white--text">
<v-icon> play_arrow </v-icon>
@ -59,11 +59,11 @@
</v-flex>
</v-layout>
</v-flex>
<v-flex md9 sm12>
<h1 style="font-size: 72px">{{ contents.title }}</h1>
<v-flex md9 sm12>
<h1 :style="fontSizes.largest">{{ contents.title }}</h1>
<h2>{{ contents.year }}</h2>
<v-layout row wrap>
<v-flex xs12 sm6 style="opacity:0.5">
<v-flex xs12 md6 style="opacity:0.5">
{{ length }}
</v-flex>
<v-flex xs12 sm6>
@ -73,12 +73,26 @@
<v-chip v-if="contents.studio" color="grey darken-2" small label> {{ contents.studio }}</v-chip>
</div>
</v-flex>
<v-flex xs12 class="text-xs-center hidden-md-and-up ">
<div v-if="playable">
<v-btn block v-if="playable && contents.Media.length == 1 && (contents.viewOffset == 0 || !contents.viewOffset)" v-on:click.native="playMedia(contents)" class="primary white--text">
<v-icon> play_arrow </v-icon>
</v-btn>
<v-btn block v-else @click.native.stop="dialog = true" class="primary white--text">
<v-icon> play_arrow </v-icon>
</v-btn>
</div>
<span v-if="!playable" class="pa-2" >Now playing on {{ chosenClient.name }} from {{ server.name }}</span>
<v-btn v-if="!playable" style="background-color: #cc3f3f" v-on:click.native="pressStop()" class="white--text">
<v-icon></v-icon> Stop
</v-btn>
</v-flex>
<p class="pt-3" style="font-style: italic"> {{ contents.summary }} </p>
<v-layout row wrap class="hidden-sm-and-down" justify-start align-start v-if="contents.type === 'movie'">
<v-flex lg3 xl2 v-if="contents.Role && contents.Role.length > 0">
<v-subheader class="white--text"> Featuring </v-subheader>
<div v-for="actor in contents.Role.slice(0, 6)" :key="actor.tag">
{{ actor.tag }} <span style="opacity:0.7;font-size:80%"> {{actor.role}} </span>
{{ actor.tag }} <span style="opacity:0.7;font-size:80%"> {{ actor.role }} </span>
</div>
</v-flex>
<v-flex lg3 xl2 v-if="contents.Director && contents.Director.length > 0">
@ -159,6 +173,23 @@
</div>
</v-flex>
</v-layout> -->
<v-divider></v-divider>
<div v-if="subsetParentData(6).length >= 0 && contents.type == 'episode' && playable" style="background: rgba(0,0,0,0.3)">
<v-subheader>Also in Season {{ contents.parentIndex }} of {{ contents.grandparentTitle }}</v-subheader>
<v-layout v-if="parentData" row wrap justify-start>
<v-flex xs6 md2 xl2 lg2 class="pb-3" v-for="ep in subsetParentData(6)" :key="ep.key">
<plexthumb bottomOnly :content="ep" :img="getLittleThumb(ep)" :class="{highlightBorder: ep.index == contents.index}" style="margin:15%" :server="server" type="thumb" spoilerFilter></plexthumb>
</v-flex>
</v-layout>
</div>
<div v-if="relatedItems.length > 0" style="background: rgba(0,0,0,0.3)">
<v-subheader>Related Movies</v-subheader>
<v-layout row wrap justify-start>
<v-flex xs4 md2 class="ma-1" v-for="movie in relatedItems" :key="movie.key">
<plexthumb :content="movie" :img="getLittleThumb(movie)" style="margin:15%" :server="server" type="thumb"></plexthumb>
</v-flex>
</v-layout>
</div>
</v-container>
<!-- <v-card-actions class="pa-4" >
<v-spacer></v-spacer>
@ -178,23 +209,7 @@
<v-icon></v-icon> Stop
</v-btn>
</v-card-actions> -->
<v-divider></v-divider>
<div v-if="subsetParentData(6).length >= 0 && contents.type == 'episode' && playable" style="background: rgba(0,0,0,0.3)">
<v-subheader>Also in Season {{ contents.parentIndex }} of {{ contents.grandparentTitle }}</v-subheader>
<v-layout v-if="parentData" row wrap justify-start>
<v-flex xs6 md2 xl2 lg2 class="pb-3" v-for="ep in subsetParentData(6)" :key="ep.key">
<plexthumb bottomOnly :content="ep" :img="getLittleThumb(ep)" :class="{highlightBorder: ep.index == contents.index}" style="margin:15%" :server="server" type="thumb" spoilerFilter @contentSet="setContent(ep)"></plexthumb>
</v-flex>
</v-layout>
</div>
<div v-if="relatedItems.length > 0 && contents.type == 'movies'" style="background: rgba(0,0,0,0.3)">
<v-subheader>Related Movies</v-subheader>
<v-layout row wrap justify-start>
<v-flex xs6 md2 xl2 lg2 class="pb-3" v-for="ep in relatedItems" :key="ep.key">
<plexthumb bottomOnly :content="ep" :img="getLittleThumb(ep)" :class="{highlightBorder: ep.index == contents.index}" style="margin:15%" :server="server" type="thumb" @contentSet="setContent(ep)"></plexthumb>
</v-flex>
</v-layout>
</div>
</div>
</v-card>
</div>
@ -217,7 +232,7 @@
</div>
</v-flex>
<v-flex xs4>
<v-btn class="primary white--text" @click.native.stop="playMedia(content,index)">
<v-btn class="primary white--text" @click.native.stop="playMedia(contents, index)">
Play
</v-btn>
</v-flex>
@ -239,29 +254,7 @@
created () {
// Hit the PMS endpoing /library/sections
var that = this
console.log('Loading content metadata: ' + this.ratingKey)
this.server.getMediaByRatingKey(this.ratingKey).then(async (result) => {
if (result) {
this.contents = result
if (result.type == 'episode'){
this.server.getSeriesChildren(result.parentKey + '/children', 0, 500, 1).then((res) => {
if (res){
this.parentData = res
}
})
}
if (result.type == 'movie'){
try {
this.related = await this.server.getRelated(this.ratingKey, 12)
} catch (e) {
console.log('Unable to fetch related content for', this.ratingKey, 'Error:', e )
}
}
this.setBackground()
} else {
this.status = 'Error loading libraries!'
}
})
},
data () {
return {
@ -284,12 +277,17 @@
}
},
mounted () {
this.getNewData()
this.fullheight = this.$refs.root.offsetHeight
this.fullwidth = this.$refs.root.offsetWidth
},
beforeDestroy () {
},
watch: {
ratingKey: function () {
this.getNewData()
}
},
computed: {
plex () {
@ -347,7 +345,7 @@
this.related.MediaContainer.Hub[0].Metadata.forEach((item) => {
items.push(item)
})
return items
return items.slice(0, 4)
},
getArtUrl () {
var w = Math.round(Math.max(document.documentElement.clientWidth, window.innerWidth || 0));
@ -383,6 +381,32 @@
},
},
methods: {
getNewData () {
console.log('Loading content metadata: ' + this.ratingKey)
this.server.getMediaByRatingKey(this.ratingKey).then(async (result) => {
if (result) {
this.contents = result.MediaContainer.Metadata[0]
if (this.contents.type == 'episode'){
this.server.getSeriesChildren(result.parentKey + '/children', 0, 500, 1).then((res) => {
if (res){
this.parentData = res
}
})
}
if (this.contents.type == 'movie'){
try {
console.log('Fetching related')
this.related = await this.server.getRelated(this.ratingKey, 12)
} catch (e) {
console.log('Unable to fetch related content for', this.ratingKey, 'Error:', e )
}
}
this.setBackground()
} else {
this.status = 'Error loading libraries!'
}
})
},
setContent (content) {
this.$router.push('/browse/' + this.serverId + '/' + content.ratingKey)
},

View File

@ -5,9 +5,9 @@
<v-progress-circular style="left: 50%; top:50%" v-bind:size="60" indeterminate class="amber--text"></v-progress-circular>
</v-flex>
</v-layout>
<div v-if="!browsingContent && contents" class="mt-3" style="height:90vh; overflow-y:scroll ">
<v-layout class="row" row wrap>
<v-flex xs4 md3 lg1 class="pb-3" v-for="content in contents.MediaContainer.Metadata" :key="content.key">
<div v-if="!browsingContent && contents" class="mt-3 mx-auto" style="height:90vh; overflow-y:scroll ">
<v-layout class="row" row wrap justify-start>
<v-flex xs4 md3 lg1 class="ma-3" v-for="content in contents.MediaContainer.Metadata" :key="content.key">
<plexthumb :content="content" :server="server" type="thumb" style="margin:7%" @contentSet="setContent(content)"></plexthumb>
</v-flex>
</v-layout>

View File

@ -6,7 +6,7 @@
</v-flex>
</v-layout>
<div v-if="contents" class="mt-3">
<v-flex xs12 style="background: rgba(0, 0, 0, .4);">
<v-flex xs12 style="background: rgba(0, 0, 0, .4);">
<v-card class="darken-2 white--text" :img="getArtUrl">
<v-container style="background:rgba(0,0,0,0.6)" class="pa-3 ma-0" fluid grid-list-lg>
<v-layout row style="height:100%">
@ -20,13 +20,13 @@
</v-flex>
<v-flex xs12 md9 class="ma-2">
<div>
<h3 > {{ contents.parentTitle }}</h3>
<h1 style="font-size: 72px"> {{ contents.parentTitle }}</h1>
<h3 style="font-weight:bold">{{ contents.title }}</h3>
<p> {{ getSeasons }} - {{ contents.parentYear }} </p>
<v-divider></v-divider>
<p style="font-style: italic" class="pt-3; overflow: hidden"> {{ contents.summary }} </p>
<div>
<v-chip v-for="genre in genres" :key="genre.tag" label>
<v-chip v-for="genre in genres" :key="genre.tag" label color="grey">
{{ genre.tag }}
</v-chip>
</div>

View File

@ -25,10 +25,25 @@
{{ content.Media.length }}
</span>
</span>
</div>
<div :style="{ 'height': bottomCalculatedHeight }" style="background: rgba(0, 0, 0, .8);position:absolute; bottom: 0; width:100%">
</div>
<v-container fill-height fluid class="pa-0" style="background: linear-gradient(to top, rgba(0, 0, 0, 5), rgba(0, 0, 0, 00)); background-position-y:bottom; background-repeat:no-repeat; background-size:100% 60%; max-width:100%">
<v-layout row wrap justify-end align-end>
<v-flex xs12>
<v-progress-linear style="width:100%" class="pa-0 mb-1 ma-0 pt-content-progress" v-if="showProgressBar" height="2" :value="unwatchedPercent"></v-progress-linear>
<v-layout align-end row wrap class="text-xs-left pa-1" style="max-width: 100%">
<v-flex xs12 v-if="!onlyBottom" style="max-width: 100%">
<div class="truncate" style="font-size:1rem">{{ getTitle(content) }}</div>
</v-flex>
<v-flex xs12 style="font-size:0.8rem" ref="bottomText">
<div class="truncate soft-text">{{ getUnder(content) }}</div>
</v-flex>
</v-layout>
</v-flex>
</v-layout>
</v-container>
<!-- <div :style="{ 'height': bottomCalculatedHeight }" style="background: rgba(0, 0, 0, .8);position:absolute; bottom: 0; width:100%">
<div class="ma-0">
<v-progress-linear style="position:absolute; top:0; width:100%" class="pa-0 ma-0 pt-content-progress" v-if="showProgressBar" height="2" :value="unwatchedPercent"></v-progress-linear>
<v-progress-linear style="position:absolute; top:0; width:100%" class="pa-0 ma-0 pt-content-progress" v-if="showProgressBar" height="2" :value="unwatchedPercent"></v-progress-linear>
<v-layout row wrap class="text-xs-left" style="margin:0; margin-left:3px; display:block; max-width:100%; height:100%">
<v-flex v-if="!onlyBottom" xs12 style="height:50%" :style="topTextStyle" ref="topText" class="pa-0 ma-0 ml-1 mt-1">
<div class="truncate" style="font-size:1rem">{{ getTitle(content) }}</div>
@ -38,7 +53,7 @@
</v-flex>
</v-layout>
</div>
</div>
</div> -->
</v-flex>
</v-layout>
</v-container>

View File

@ -1,23 +1,22 @@
<template>
<div style="width:100%; max-height: calc(100vh - 64px)">
<videoplayer v-if="playingMetadata && chosenServer && chosenQuality && ready"
@playerMounted="playerMounted()"
@timelineUpdate="timelineUpdate"
@playbackEnded="stopPlayback()"
@playerMounted="playerMounted()"
@timelineUpdate="timelineUpdate"
@playbackEnded="stopPlayback()"
:metadata="playingMetadata"
:server="chosenServer"
:src="getSourceByLabel(chosenQuality)"
:initUrl="getSourceByLabel(chosenQuality).initUrl"
:params="getSourceByLabel(chosenQuality).params"
:initialOffset="playertime"
:createdAt="playerCreatedAt"
:metadata="playingMetadata"
:server="chosenServer"
:src="getSourceByLabel(chosenQuality)"
:initUrl="getSourceByLabel(chosenQuality).initUrl"
:params="getSourceByLabel(chosenQuality).params"
:initialOffset="playertime"
:createdAt="playerCreatedAt"
></videoplayer>
<v-dialog v-model="dialog">
<v-card>
<v-card-title>Playback Settings </v-card-title>
<v-card-text>
<v-card-text>
<v-select
v-model="chosenQuality"
:items="qualitiesSelect"
@ -68,10 +67,11 @@
<v-btn primary v-on:click.native.stop="dialog = !dialog">Playback Settings</v-btn>
</v-flex>
<v-flex md2>
<v-btn error v-on:click.native="stopPlayback()">Stop playback</v-btn>
<router-link to="/browse">
<v-btn error v-on:click.native="stopPlayback()">Stop playback</v-btn>
</router-link>
</v-flex>
</v-layout>
</div>
</template>
@ -79,7 +79,7 @@
// CSS imports
var request = require('request')
var parseXMLString = require('xml2js').parseString;
var parseXMLString = require('xml2js').parseString
// Components
import videoplayer from './ptplayer/videoplayer.vue'
@ -91,7 +91,19 @@
created () {
},
mounted: function () {
var that = this
// Check if we have params
if (this.$route.query.start) {
// We need to auto play
let query = this.$route.query
this.chosenKey = query.key.replace('/library/metadata/', '')
this.chosenMediaIndex = query.mediaIndex || 0
this.chosenServer = this.plex.servers[query.chosenServer]
this.playertime = query.offset
let oldtime = this.playertime
let oldkey = this.chosenKey
let checkers = 0
}
// Similuate a real plex client
this.eventbus.$on('command', (data) => {
@ -148,31 +160,6 @@
})
return
}
if (data.command == '/player/playback/playMedia') {
this.chosenKey = data.params.key.replace('/library/metadata/', '')
this.chosenMediaIndex = data.params.mediaIndex || 0
this.chosenServer = this.plex.servers[data.params.machineIdentifier]
this.playertime = data.params.offset
let oldtime = this.playertime
let oldkey = this.chosenKey
let checkers = 0
let tick = setInterval(() => {
console.log('Checking..')
if (Math.abs(parseInt(this.playertime) - parseInt(oldtime) ) > 1000) {
console.log('STARTED PLAYING!')
clearInterval(tick)
return data.callback(true)
}
checkers++
if (checkers > 300 || oldkey != this.chosenKey) {
console.log('Timeout reached on playMedia')
// It has been 30 seconds since - fail
clearInterval(tick)
return data.callback(false)
}
}, 100)
}
console.log('Unable to process the remote control command ' + data.command)
})
@ -221,7 +208,7 @@
chosenQuality: function () {
this.changedPlaying(false)
//console.log('Our new preferred quality is now ' + this.chosenQuality )
this.$store.commit('setSettingPTPLAYERQUALITY',this.chosenQuality)
this.$store.commit('setSettingPTPLAYERQUALITY', this.chosenQuality)
},
chosenMediaIndex: function () {
this.chosenSubtitleIndex = 0
@ -450,7 +437,7 @@
stopPlayback () {
console.log('Stopped Playback')
this.$store.commit('SET_DECISIONBLOCKED', false)
request(this.getSourceByLabel(this.chosenQuality).stopUrl, function (error, response, body) {})
request(this.getSourceByLabel(this.chosenQuality).stopUrl, (error, response, body) => {})
this.playerstatus = 'stopped'
this.sessionId = this.generateGuid()
this.xplexsession = this.generateGuid()
@ -462,23 +449,22 @@
var that = this
this.ready = false
this.$store.commit('SET_DECISIONBLOCKED', false)
//console.log('Changed what we are meant to be playing!')
console.log('Changed what we are meant to be playing!', changeItem)
if (!this.chosenKey || !this.chosenServer) {
this.playerstatus = 'stopped'
this.playerMetadata = null
return
}
function req () {
that.sources = that.generateSources()
request(that.getSourceByLabel(that.chosenQuality).initUrl, function (error, response, body) {
parseXMLString(body, function (err, result) {
const req = () => {
this.sources = this.generateSources()
request(this.getSourceByLabel(this.chosenQuality).initUrl, (error, response, body) => {
parseXMLString(body, (err, result) => {
if (err) {
that.ready = false
this.ready = false
}
that.ready = true
that.transcodeSessionMetadata = result
this.ready = true
this.transcodeSessionMetadata = result
})
if (!error) {
@ -487,15 +473,15 @@
}
if (this.playingMetadata) {
request(this.getSourceByLabel(this.chosenQuality).stopUrl, function (error, response, body) {
request(this.getSourceByLabel(this.chosenQuality).stopUrl, (error, response, body) => {
// We dont need to know what this resulted in
})
}
if (changeItem) {
if (changeItem || !this.playingMetadata) {
this.playingMetadata = null
this.chosenServer.getMediaByRatingKey(this.chosenKey, function (result) {
//console.log(result)
that.playingMetadata = result
this.chosenServer.getMediaByRatingKey(this.chosenKey).then((result) => {
console.log(result)
this.playingMetadata = result.MediaContainer.Metadata[0]
req()
})
} else {
@ -526,7 +512,7 @@
session: this.sessionId,
'X-Plex-Product': 'SyncLounge',
'X-Plex-Version': '3.4.1',
'X-Plex-Client-Identifier': 'SyncLoungeWeb',
'X-Plex-Client-Identifier': 'SyncLounge',
'X-Plex-Platform': this.browser,
'X-Plex-Platform-Version': '57.0',
'X-Plex-Device': 'Windows',
@ -587,7 +573,7 @@
'X-Plex-Chunked': 1,
'X-Plex-Product': 'SyncLounge',
'X-Plex-Version': '3.4.1',
'X-Plex-Client-Identifier': 'SyncLoungePlayer',
'X-Plex-Client-Identifier': 'SyncLounge',
'X-Plex-Platform': 'SyncLounge',
'X-Plex-Platform-Version': '57.0',
'X-Plex-Device': 'HTML TV App',
@ -616,7 +602,7 @@
'timeout': 1,
'X-Plex-Product': 'SyncLounge',
'X-Plex-Version': '3.4.1',
'X-Plex-Client-Identifier': 'SyncLoungePlayer',
'X-Plex-Client-Identifier': 'SyncLounge',
'X-Plex-Platform': that.browser,
'X-Plex-Platform-Version': '57.0',
'X-Plex-Device': 'Windows',
@ -653,7 +639,6 @@
.toString(16)
.substring(1);
}
return s4() + s4() + s4() + s4();
},
getBrowser () {

View File

@ -318,13 +318,13 @@
this.player.currentTime(this.initialOffset / 1000)
player.on(['waiting', 'pause'], function () {
that.isPlaying = 'paused';
});
player.on(['waiting', 'pause'], () => {
this.isPlaying = 'paused';
})
player.on('playing', function () {
that.isPlaying = 'playing';
});
player.on('playing', () => {
this.isPlaying = 'playing';
})
// Setup our intervals for pinging the transcoder and timelines
function send () {
@ -335,7 +335,7 @@
if (!that.player || !that.metadata) {
return
}
var query = '';
var query = ''
let params = {
hasMDE: 1,
ratingKey: that.metadata.ratingKey,
@ -362,14 +362,14 @@
timeout: 2000,
url: url
}
request(url, function (error, response, body) {
request(url, (error, response, body) => {
if (!error) {
// console.log('Succesfully sent Player status to PMS')
}
})
}
this.ticker = setInterval(function () {
this.ticker = setInterval(() => {
// Tell the PMS instance of our status
send()
}, 10000)

View File

@ -34,6 +34,22 @@ Vue.config.productionTip = false
// Our Event bus
window.EventBus = new Vue()
window.EventBus.$on('command', (data) => {
if (data.command === '/player/playback/playMedia') {
router.push(
{
path: '/player',
query: {
start: true,
key: data.params.key.replace('/library/metadata/', ''),
mediaIndex: data.params.mediaIndex || 0,
chosenServer: data.params.machineIdentifier,
playertime: data.params.offset
}
}
)
}
})
Vue.mixin({
computed: {
@ -57,6 +73,15 @@ Vue.mixin({
},
plexserver: function () {
return this.plex.servers[this.$route.params.machineIdentifier]
},
fontSizes: function () {
var w = Math.round(Math.max(document.documentElement.clientWidth, window.innerWidth || 0))
var h = Math.round(Math.max(document.documentElement.clientHeight, window.innerHeight || 0))
let maxPx = 94
let maxRes = 3000
return {
largest: { 'font-size': ((w / maxRes) * maxPx) + 'px' }
}
}
}
})

View File

@ -21,7 +21,7 @@ export default new Router({
{ path: '/clientselect', component: require('../components/application/walkthrough.vue') },
{ path: '/joinroom', component: require('../components/application/joinroom.vue') },
{ path: '/player', component: require('../components/application/ptplayer.vue') },
{ path: '/player', meta: { protected: true }, component: require('../components/application/ptplayer.vue') },
{ path: '/browse', meta: { protected: true }, name: 'browse', component: require('../components/application/plexbrowser.vue') },

View File

@ -93,7 +93,7 @@ const state = {
const mutations = {
SET_CHOSENCLIENT (state, client) {
async function playbackChange (ratingKey) {
console.log('Playback change!', ratingKey)
// console.log('Playback change!', ratingKey)
if (ratingKey != null) {
// Playing something different!
let server = state.plex.servers[state.chosenClient.lastTimelineObject.machineIdentifier]
@ -103,8 +103,9 @@ const mutations = {
return
}
// Fetch our metadata from this server
console.log('Loading content metadata from store ' + ratingKey)
server.getMediaByRatingKey(ratingKey.replace('/library/metadata/', ''), function (metadata) {
// console.log('Loading content metadata from store ' + ratingKey)
server.getMediaByRatingKey(ratingKey.replace('/library/metadata/', '')).then((data) => {
let metadata = data.MediaContainer.Metadata[0]
if (!metadata) {
return
}
@ -129,7 +130,7 @@ const mutations = {
}
function newTimeline (timeline) {
console.log('Got timeline')
// console.log('Got timeline')
// Lets send this to our PTServer
state.ourClientResponseTime = timeline.lastResponseTime
let title = null
@ -156,9 +157,9 @@ const mutations = {
let playerState = null
let showName = null
if (state.plextogether._socket) {
state.plextogether._socket.pollStartTime = (new Date).getTime()
state.plextogether._socket.emit('poll', end_obj)
if (state.synclounge._socket) {
state.synclounge._socket.pollStartTime = (new Date).getTime()
state.synclounge._socket.emit('poll', end_obj)
}
}

View File

@ -1,5 +1,8 @@
export default {
getItemCache: (state) => {
return state.itemCache
},
getLibraryCache: (state) => {
return state.libraryCache
}
};

View File

@ -137,7 +137,7 @@ module.exports = function PlexClient () {
return false
}
} catch (e) {
console.log(e)
// console.log(e)
return false
}
}

View File

@ -58,6 +58,7 @@ module.exports = function PlexServer () {
request(options, (error, response, body) => {
if (!error) {
let parsed = JSON.parse(body)
console.log('Metadata request result', parsed)
this.handleMetadata(parsed)
return resolve(parsed)
}
@ -138,8 +139,17 @@ module.exports = function PlexServer () {
this.getMediaByRatingKey = async function (ratingKey) {
//This function hits the PMS and returns the item at the ratingKey
let data = await this.hitApi('/library/metadata/' + ratingKey, {})
return this.handleMetadata(data)
try {
let data = await this.hitApi('/library/metadata/' + ratingKey, {})
if (data && data.MediaContainer.librarySectionID) {
this.commit('SET_LIBRARYCACHE', [data.MediaContainer.librarySectionID, this.clientIdentifier, data.MediaContainer.librarySectionTitle])
}
return data
} catch (e) {
console.log(e)
return false
}
// return this.handleMetadata(data)
}
this.markWatchedByRatingKey = function (ratingKey) {
return this.hitApi('/:/scrobble', {
@ -175,19 +185,31 @@ module.exports = function PlexServer () {
throw new Error(e)
}
}
this.getAllLibraries = function () {
return this.hitApi('/library/sections', {})
this.getAllLibraries = async function () {
try {
let data = await this.hitApi('/library/sections', {})
console.log('Library data', data)
if (data && data.MediaContainer) {
data.MediaContainer.Directory.forEach((library) => {
this.commit('SET_LIBRARYCACHE', [library.key, this.clientIdentifier, library.title ])
})
}
return data
} catch (e) {
return false
}
}
this.getLibraryContents = async function (key, start, size) {
try {
let data = await this.hitApi('/library/sections/' + key + '/all', {
'X-Plex-Container-Start': start,
'X-Plex-Container-Size': size
'X-Plex-Container-Size': size,
'excludeAllLeaves': 1
})
for (let i = 0; i < data.MediaContainer.Metadata.length; i++) {
data.MediaContainer.Metadata[i].librarySectionID = key
this.commit('SET_ITEMCACHE', [data.MediaContainer.Metadata[i].ratingKey,
data.MediaContainer.Metadata[i]])
// this.commit('SET_ITEMCACHE', [data.MediaContainer.Metadata[i].ratingKey,
// data.MediaContainer.Metadata[i]])
}
return data
} catch (e) {
@ -250,36 +272,21 @@ module.exports = function PlexServer () {
}
this.handleMetadata = function (result) {
if (result != null) {
if (result._children) {
// Old Server version compatibility
for (var i in result._children) {
var res = result._children[i]
if (res._elementType == 'Directory' || res._elementType == 'Media' || res._elementType == 'Video') {
res.machineIdentifier = this.clientIdentifier
return res
if (result) {
if (result.MediaContainer && result.MediaContainer.Metadata && result.MediaContainer.Metadata.length > 0) {
for (let i = 0; i < result.MediaContainer.Metadata.length; i++) {
result.MediaContainer.Metadata[i].machineIdentifier = this.clientIdentifier
if (result.MediaContainer.Metadata[i].ratingKey) {
this.commit('SET_ITEMCACHE', [result.MediaContainer.Metadata[i].ratingKey,
result.MediaContainer.Metadata[i]])
}
}
} else {
// New Server compatibility
if (result.MediaContainer && result.MediaContainer.Metadata && result.MediaContainer.Metadata.length > 0) {
for (let i = 0; i < result.MediaContainer.Metadata.length; i++) {
result.MediaContainer.Metadata[i].machineIdentifier = this.clientIdentifier
if (result.MediaContainer.Metadata[i].ratingKey) {
this.commit('SET_ITEMCACHE', [result.MediaContainer.Metadata[i].ratingKey,
result.MediaContainer.Metadata[i]])
}
}
return
} else {
if (result.MediaContainer.ratingKey) {
this.commit('SET_ITEMCACHE', [result.MediaContainer.ratingKey, result.MediaContainer])
}
return
if (result.MediaContainer.ratingKey) {
this.commit('SET_ITEMCACHE', [result.MediaContainer.ratingKey, result.MediaContainer])
}
return result.MediaContainer.Metadata[0]
}
return null
return result.MediaContainer.Metadata
}
}
}

View File

@ -41,10 +41,20 @@ export default {
state.clients[client.clientIdentifier].chosenConnection = connection
},
SET_ITEMCACHE: (state, data) => {
// return
let [ratingKey, newData] = data
if (!state.itemCache[newData.machineIdentifier]) {
state.itemCache[newData.machineIdentifier] = {}
}
state.itemCache[newData.machineIdentifier][ratingKey] = newData
},
SET_LIBRARYCACHE: (state, data) => {
// return
console.log('Setting library cache', data)
let [id, machineIdentifier, newData] = data
if (!state.libraryCache[machineIdentifier]) {
state.libraryCache[machineIdentifier] = {}
}
state.libraryCache[machineIdentifier][id] = newData
}
};

View File

@ -7,6 +7,7 @@ export default {
servers: {},
itemCache: {},
libraryCache: {},
chosenClient: null,