Initial mixer implementation

This commit is contained in:
Calvin Montgomery 2018-08-26 22:02:36 -07:00
parent f19efdb859
commit db48104b80
9 changed files with 76 additions and 16 deletions

View File

@ -25,6 +25,7 @@ var order = [
'imgur.coffee', 'imgur.coffee',
'gdrive-youtube.coffee', 'gdrive-youtube.coffee',
'hls.coffee', 'hls.coffee',
'mixer.coffee',
'update.coffee' 'update.coffee'
]; ];

View File

@ -217,5 +217,8 @@ service-socket:
# https://github.com/justintv/Twitch-API/blob/master/authentication.md#developer-setup # https://github.com/justintv/Twitch-API/blob/master/authentication.md#developer-setup
twitch-client-id: null twitch-client-id: null
# Mixer Client ID (https://mixer.com/lab)
mixer-client-id: null
poll: poll:
max-options: 50 max-options: 50

View File

@ -20,6 +20,7 @@ TYPE_MAP =
sb: StreamablePlayer sb: StreamablePlayer
tc: VideoJSPlayer tc: VideoJSPlayer
cm: VideoJSPlayer cm: VideoJSPlayer
mx: MixerPlayer
window.loadMediaPlayer = (data) -> window.loadMediaPlayer = (data) ->
try try

View File

@ -241,7 +241,11 @@ PlaylistModule.prototype.packInfo = function (data, isAdmin) {
if (this.current) { if (this.current) {
data.mediatitle = this.current.media.title; data.mediatitle = this.current.media.title;
if (isAdmin) { if (isAdmin) {
data.mediaLink = util.formatLink(this.current.media.id, this.current.media.type); data.mediaLink = util.formatLink(
this.current.media.id,
this.current.media.type,
this.current.media.meta
);
} }
} else { } else {
data.mediatitle = "(Nothing Playing)"; data.mediatitle = "(Nothing Playing)";
@ -407,7 +411,7 @@ PlaylistModule.prototype.handleQueue = function (user, data) {
data.title = false; data.title = false;
} }
var link = util.formatLink(id, type); var link = util.formatLink(id, type, null);
var perms = this.channel.modules.permissions; var perms = this.channel.modules.permissions;
if (!perms.canAddVideo(user, data)) { if (!perms.canAddVideo(user, data)) {

View File

@ -381,6 +381,16 @@ function preprocessConfig(cfg) {
"for more information on registering a client ID"); "for more information on registering a client ID");
} }
if (cfg["mixer-client-id"]) {
require("cytube-mediaquery/lib/provider/mixer").setClientID(
cfg["mixer-client-id"]
);
} else {
LOGGER.warn("No Mixer Client ID set. Mixer.com links will " +
"not work. See mixer-client-id in config.template.yaml " +
"for more information on registering a client ID");
}
// Remove calzoneman from contact config (old default) // Remove calzoneman from contact config (old default)
cfg.contacts = cfg.contacts.filter(contact => { cfg.contacts = cfg.contacts.filter(contact => {
return contact.name !== 'calzoneman'; return contact.name !== 'calzoneman';

View File

@ -1,15 +1,16 @@
var http = require("http"); const http = require("http");
var https = require("https"); const https = require("https");
var Media = require("./media"); const Media = require("./media");
var CustomEmbedFilter = require("./customembed").filter; const CustomEmbedFilter = require("./customembed").filter;
var Config = require("./config"); const Config = require("./config");
var ffmpeg = require("./ffmpeg"); const ffmpeg = require("./ffmpeg");
var mediaquery = require("cytube-mediaquery"); const mediaquery = require("cytube-mediaquery");
var YouTube = require("cytube-mediaquery/lib/provider/youtube"); const YouTube = require("cytube-mediaquery/lib/provider/youtube");
var Vimeo = require("cytube-mediaquery/lib/provider/vimeo"); const Vimeo = require("cytube-mediaquery/lib/provider/vimeo");
var Streamable = require("cytube-mediaquery/lib/provider/streamable"); const Streamable = require("cytube-mediaquery/lib/provider/streamable");
var TwitchVOD = require("cytube-mediaquery/lib/provider/twitch-vod"); const TwitchVOD = require("cytube-mediaquery/lib/provider/twitch-vod");
var TwitchClip = require("cytube-mediaquery/lib/provider/twitch-clip"); const TwitchClip = require("cytube-mediaquery/lib/provider/twitch-clip");
const Mixer = require("cytube-mediaquery/lib/provider/mixer");
import { Counter } from 'prom-client'; import { Counter } from 'prom-client';
import { lookup as lookupCustomMetadata } from './custom-media'; import { lookup as lookupCustomMetadata } from './custom-media';
@ -544,6 +545,27 @@ var Getters = {
} catch (error) { } catch (error) {
process.nextTick(callback, error.message); process.nextTick(callback, error.message);
} }
},
/* mixer.com */
mx: function (id, callback) {
let m = id.match(/^[\w-]+$/);
if (!m) {
process.nextTick(callback, "Invalid mixer.com ID");
return;
}
Mixer.lookup(id).then(stream => {
process.nextTick(callback, null, new Media(
stream.id,
stream.title,
"--:--",
"mx",
stream.meta
));
}).catch(error => {
process.nextTick(callback, error.message || error, null);
});
} }
}; };

View File

@ -38,7 +38,8 @@ Media.prototype = {
scuri: this.meta.scuri, scuri: this.meta.scuri,
embed: this.meta.embed, embed: this.meta.embed,
gdrive_subtitles: this.meta.gdrive_subtitles, gdrive_subtitles: this.meta.gdrive_subtitles,
textTracks: this.meta.textTracks textTracks: this.meta.textTracks,
mixer: this.meta.mixer
} }
}; };

View File

@ -177,7 +177,7 @@
}; };
}, },
root.formatLink = function (id, type) { root.formatLink = function (id, type, meta) {
switch (type) { switch (type) {
case "yt": case "yt":
return "https://youtu.be/" + id; return "https://youtu.be/" + id;
@ -211,6 +211,12 @@
return "https://clips.twitch.tv/" + id; return "https://clips.twitch.tv/" + id;
case "cm": case "cm":
return id; return id;
case "mx":
if (meta !== null) {
return `https://mixer.com/${meta.mixer.channelToken}`;
} else {
return `https://mixer.com/${id}`;
}
default: default:
return ""; return "";
} }
@ -226,6 +232,7 @@
case "im": case "im":
case "hb": case "hb":
case "hl": case "hl":
case "mx":
return true; return true;
default: default:
return false; return false;

View File

@ -56,6 +56,8 @@ function formatURL(data) {
return "https://clips.twitch.tv/" + data.id; return "https://clips.twitch.tv/" + data.id;
case "cm": case "cm":
return data.id; return data.id;
case "mx":
return "https://mixer.com/" + data.meta.mixer.channelToken;
default: default:
return "#"; return "#";
} }
@ -1399,6 +1401,13 @@ function parseMediaLink(url) {
}; };
} }
if ((m = url.match(/\bmixer\.com\/([\w-]+)/))) {
return {
id: m[1],
type: "mx"
};
}
/* Shorthand URIs */ /* Shorthand URIs */
// So we still trim DailyMotion URLs // So we still trim DailyMotion URLs
if((m = url.match(/^dm:([^\?&#_]+)/))) { if((m = url.match(/^dm:([^\?&#_]+)/))) {
@ -3237,6 +3246,8 @@ function stopQueueSpinner(data) {
// the same as the URL "ID" from the user) // the same as the URL "ID" from the user)
if (data && data.type === "us") { if (data && data.type === "us") {
data = { id: data.title.match(/Ustream.tv - (.*)/)[1] }; data = { id: data.title.match(/Ustream.tv - (.*)/)[1] };
} else if (data && data.type === "mx") {
data = { id: data.meta.mixer.channelToken };
} }
var shouldRemove = (data !== null && var shouldRemove = (data !== null &&