streamer as separate application; working streamer monitor interface
This commit is contained in:
		
							
								
								
									
										98
									
								
								assets/streamer/controllers.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								assets/streamer/controllers.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,98 @@
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
 | 
			
		||||
import Model from 'public/model';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export class Streamer extends Model {
 | 
			
		||||
    get queues() { return this.data ? this.data.queues : []; }
 | 
			
		||||
    get playlists() { return this.data ? this.data.playlists : []; }
 | 
			
		||||
    get sources() { return [...this.queues, ...this.playlists]; }
 | 
			
		||||
    get source() { return this.sources.find(o => o.id == this.data.source) }
 | 
			
		||||
 | 
			
		||||
    commit(data) {
 | 
			
		||||
        if(!this.data)
 | 
			
		||||
            this.data = { id: data.id, playlists: [], queues: [] }
 | 
			
		||||
 | 
			
		||||
        data.playlists = Playlist.updateList(data.playlists, this.playlists)
 | 
			
		||||
        data.queues = Queue.updateList(data.queues, this.queues)
 | 
			
		||||
        super.commit(data)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class Request extends Model {
 | 
			
		||||
    static getId(data) { return data.rid; }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class Source extends Model {
 | 
			
		||||
    constructor(...args) {
 | 
			
		||||
        super(...args);
 | 
			
		||||
        setInterval(() => this.tick(), 1000)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get isQueue() { return false; }
 | 
			
		||||
    get isPlaylist() { return false; }
 | 
			
		||||
    get isPlaying() { return this.data.status == 'playing' }
 | 
			
		||||
    get isPaused() { return this.data.status == 'paused' }
 | 
			
		||||
 | 
			
		||||
    get remainingString() {
 | 
			
		||||
        if(!this.remaining)
 | 
			
		||||
            return '00:00';
 | 
			
		||||
 | 
			
		||||
        const seconds = Math.floor(this.remaining % 60);
 | 
			
		||||
        const minutes = Math.floor(this.remaining / 60);
 | 
			
		||||
        return String(minutes).padStart(2, '0') + ':' +
 | 
			
		||||
               String(seconds).padStart(2, '0');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    sync() { return this.action('sync/', {method: 'POST'}, true); }
 | 
			
		||||
    skip() { return this.action('skip/', {method: 'POST'}, true); }
 | 
			
		||||
    restart() { return this.action('restart/', {method: 'POST'}, true); }
 | 
			
		||||
 | 
			
		||||
    seek(count) {
 | 
			
		||||
        return this.action('seek/', {
 | 
			
		||||
            method: 'POST',
 | 
			
		||||
            body: JSON.stringify({count: count})
 | 
			
		||||
        }, true)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    tick() {
 | 
			
		||||
        if(!this.data.remaining || !this.isPlaying)
 | 
			
		||||
            return;
 | 
			
		||||
        const delta = (Date.now() - this.commitDate) / 1000;
 | 
			
		||||
        Vue.set(this, 'remaining', this.data.remaining - delta)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    commit(data) {
 | 
			
		||||
        if(data.air_time)
 | 
			
		||||
            data.air_time = new Date(data.air_time);
 | 
			
		||||
        Vue.set(this, 'remaining', data.remaining)
 | 
			
		||||
        this.commitDate = Date.now()
 | 
			
		||||
        super.commit(data)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export class Playlist extends Source {
 | 
			
		||||
    get isPlaylist() { return true; }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export class Queue extends Source {
 | 
			
		||||
    get isQueue() { return true; }
 | 
			
		||||
    get queue() { return this.data && this.data.queue; }
 | 
			
		||||
 | 
			
		||||
    commit(data) {
 | 
			
		||||
        data.queue = Request.updateList(data.queue, this.queue)
 | 
			
		||||
        super.commit(data)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    push(soundId) {
 | 
			
		||||
        return this.action('push/', {
 | 
			
		||||
            method: 'POST',
 | 
			
		||||
            body: JSON.stringify({'sound_id': parseInt(soundId)})
 | 
			
		||||
        }, true);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										56
									
								
								assets/streamer/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								assets/streamer/index.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,56 @@
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import Button from 'buefy/dist/components/button';
 | 
			
		||||
 | 
			
		||||
Vue.use(Button)
 | 
			
		||||
 | 
			
		||||
import {setAppConfig} from 'public/app';
 | 
			
		||||
import Model from 'public/model';
 | 
			
		||||
import Sound from 'public/sound';
 | 
			
		||||
import {Streamer, Queue} from './controllers';
 | 
			
		||||
 | 
			
		||||
window.aircox.appConfig = {
 | 
			
		||||
    data() {
 | 
			
		||||
        return {
 | 
			
		||||
            // current streamer
 | 
			
		||||
            streamer: null,
 | 
			
		||||
            // all streamers
 | 
			
		||||
            streamers: [],
 | 
			
		||||
            // fetch interval id
 | 
			
		||||
            fetchInterval: null,
 | 
			
		||||
 | 
			
		||||
            Sound: Sound,
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    computed: {
 | 
			
		||||
        apiUrl() {
 | 
			
		||||
            return this.$el && this.$el.dataset.apiUrl;
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        sources() {
 | 
			
		||||
            var sources = this.streamer ? this.streamer.sources : [];
 | 
			
		||||
            return sources.filter(s => s.data)
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    methods: {
 | 
			
		||||
        fetchStreamers() {
 | 
			
		||||
            Streamer.fetchAll(this.apiUrl, null)
 | 
			
		||||
                .then(streamers => {
 | 
			
		||||
                    Vue.set(this, 'streamers', streamers);
 | 
			
		||||
                    Vue.set(this, 'streamer', streamers ? streamers[0] : null);
 | 
			
		||||
                })
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    mounted() {
 | 
			
		||||
        this.fetchStreamers();
 | 
			
		||||
        this.fetchInterval = setInterval(() => this.streamer && this.streamer.fetch(), 5000)
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    destroyed() {
 | 
			
		||||
        if(this.fetchInterval !== null)
 | 
			
		||||
            clearInterval(this.fetchInterval)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user