Added stream URL to channel settings.
This commit is contained in:
parent
e4bebce431
commit
93265b7890
|
|
@ -64,6 +64,10 @@ const channelSchema = new mongoose.Schema({
|
|||
required: true,
|
||||
default: true
|
||||
},
|
||||
streamURL: {
|
||||
type: mongoose.SchemaTypes.String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
permissions: {
|
||||
type: channelPermissionSchema,
|
||||
|
|
|
|||
|
|
@ -32,8 +32,15 @@ module.exports.yankMedia = async function(url, title){
|
|||
//return media object list from IA module
|
||||
return await iaUtil.fetchMetadata(pullType.id, title);
|
||||
case "yt":
|
||||
//return mediao object list from the YT-DLP module's youtube function
|
||||
//return media object list from the YT-DLP module's youtube function
|
||||
return await ytdlpUtil.fetchYoutubeMetadata(pullType.id, title);
|
||||
case "ytp":
|
||||
//return media object list from YT-DLP module's youtube playlist function
|
||||
//return await ytdlpUtil.fetchYoutubePlaylistMetadata(pullType.id, title);
|
||||
//Holding off on this since YT-DLP takes 10 years to do a playlist as it needs to pull each and every video one-by-one
|
||||
//Maybe in the future a piped alternative might be in order, however this would most likely require us to host our own local instance.
|
||||
//Though it could give us added resistance against youtube/google's rolling IP bans
|
||||
return null;
|
||||
case "dm":
|
||||
//return mediao object list from the YT-DLP module's dailymotion function
|
||||
return await ytdlpUtil.fetchDailymotionMetadata(pullType.id, title);
|
||||
|
|
@ -85,7 +92,7 @@ module.exports.getMediaType = async function(url){
|
|||
|
||||
//If we have link to a resource from archive.org
|
||||
if(match = url.match(/archive\.org\/(?:details|download)\/([a-zA-Z0-9\/._-\s\%]+)/)){
|
||||
//return internet archive code
|
||||
//return internet archive upload id and filepath
|
||||
return {
|
||||
type: "ia",
|
||||
id: match[1]
|
||||
|
|
@ -101,6 +108,15 @@ module.exports.getMediaType = async function(url){
|
|||
}
|
||||
}
|
||||
|
||||
//If we have a match to a youtube playlist
|
||||
if((match = url.match(/youtube\.com\/playlist\?list=([a-zA-Z0-9_-]{34})/)) || (match = url.match(/youtu\.be\/playlist\?list=([a-zA-Z0-9_-]{34})/))){
|
||||
//return youtube playlist id
|
||||
return {
|
||||
type: "ytp",
|
||||
id: match[1]
|
||||
}
|
||||
}
|
||||
|
||||
//If we have a match to a dailymotion video
|
||||
if(match = url.match(/dailymotion\.com\/video\/([a-z0-9]{7})/)){
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -32,7 +32,28 @@ const loggerUtils = require('../loggerUtils.js')
|
|||
module.exports.fetchYoutubeMetadata = async function(id, title){
|
||||
try{
|
||||
//Try to pull media from youtube id
|
||||
const media = await fetchMetadata(`https://youtu.be/${id}`, title, 'yt');
|
||||
const media = await fetchVideoMetadata(`https://youtu.be/${id}`, title, 'yt');
|
||||
|
||||
//Return found media
|
||||
return media;
|
||||
//If something went wrong
|
||||
}catch(err){
|
||||
//If our IP was banned by youtube
|
||||
if(err.message.match("Sign in to confirm you’re not a bot.")){
|
||||
//Make our own error with blackjack and hookers
|
||||
throw loggerUtils.exceptionSmith("The server's IP address has been banned by youtube. Please contact your server's administrator.", "queue");
|
||||
//Otherwise if we don't have a good way to handle it
|
||||
}else{
|
||||
//toss it back up
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.fetchYoutubePlaylistMetadata = async function(id, title){
|
||||
try{
|
||||
//Try to pull media from youtube id
|
||||
const media = await fetchPlaylistMetadata(`https://youtu.be/playlist?list=${id}`, title, 'yt');
|
||||
|
||||
//Return found media
|
||||
return media;
|
||||
|
|
@ -52,22 +73,19 @@ module.exports.fetchYoutubeMetadata = async function(id, title){
|
|||
|
||||
module.exports.fetchDailymotionMetadata = async function(id, title){
|
||||
//Pull media from dailymotion link
|
||||
const media = await fetchMetadata(`https://dailymotion.com/video/${id}`, title, 'dm');
|
||||
const media = await fetchVideoMetadata(`https://dailymotion.com/video/${id}`, title, 'dm');
|
||||
|
||||
//Return found media;
|
||||
return media;
|
||||
}
|
||||
|
||||
//Generic YTDLP function meant to be used by service-sepecific fetchers which will then be used to fetch video metadata
|
||||
async function fetchMetadata(link, title, type, format = 'b'){
|
||||
//Generic single video YTDLP function meant to be used by service-sepecific fetchers which will then be used to fetch video metadata
|
||||
async function fetchVideoMetadata(link, title, type, format = 'b'){
|
||||
//Create media list
|
||||
const mediaList = [];
|
||||
|
||||
//Pull raw metadata
|
||||
const rawMetadata = await ytdlp(link, {
|
||||
dumpSingleJson: true,
|
||||
format
|
||||
});
|
||||
//Pull raw metadata from YT-DLP
|
||||
const rawMetadata = await ytdlpFetch(link, format);
|
||||
|
||||
//Pull data from rawMetadata, sanatizing title to prevent XSS
|
||||
const name = validator.escape(validator.trim(rawMetadata.title));
|
||||
|
|
@ -85,4 +103,17 @@ async function fetchMetadata(link, title, type, format = 'b'){
|
|||
|
||||
//Return list of media
|
||||
return mediaList;
|
||||
}
|
||||
|
||||
//YT-DLP takes forever to handle playlists, we'll handle this via piped in the future perhaps
|
||||
/*async function fetchPlaylistMetadata(link, title, type, format = 'b'){
|
||||
}*/
|
||||
|
||||
//Wrapper function for YT-DLP NPM package with pre-set cli-flags
|
||||
async function ytdlpFetch(link, format = 'b'){
|
||||
//return promise from ytdlp
|
||||
return ytdlp(link, {
|
||||
dumpSingleJson: true,
|
||||
format
|
||||
});
|
||||
}
|
||||
|
|
@ -80,6 +80,11 @@ module.exports.settingsMap = function(){
|
|||
optional: true,
|
||||
isBoolean: true,
|
||||
errorMessage: "Bad channel settings map."
|
||||
},
|
||||
'settingsMap.streamURL': {
|
||||
optional: true,
|
||||
isURL: true,
|
||||
errorMessage: "Invalid Stream URL"
|
||||
}
|
||||
})
|
||||
);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,14 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. %>
|
|||
<% Object.keys(channel.settings).forEach((key) => { %>
|
||||
<span class="admin-list-field-container">
|
||||
<label class="admin-list-label"><%- key %>:</label>
|
||||
<input id=<%- `channel-preference-${key}` %> class="channel-preference-list-item" type="checkbox" <% if(channel.settings[key]){ %> checked <% } %>>
|
||||
<% switch(typeof channel.settings[key]){
|
||||
case "string": %>
|
||||
<input id=<%- `channel-preference-${key}` %> class="channel-preference-list-item" value="<%- channel.settings[key] %>">
|
||||
<% break;
|
||||
default: %>
|
||||
<input id=<%- `channel-preference-${key}` %> class="channel-preference-list-item" type="checkbox" <% if(channel.settings[key]){ %> checked <% } %>>
|
||||
<% break;
|
||||
} %>
|
||||
</span>
|
||||
<% }); %>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -235,13 +235,28 @@ class prefrenceList{
|
|||
}
|
||||
|
||||
async submitUpdate(event){
|
||||
//Get key from event target
|
||||
const key = event.target.id.replace("channel-preference-","");
|
||||
const value = event.target.checked;
|
||||
|
||||
//Pull value from event target
|
||||
let value = event.target.value;
|
||||
|
||||
//If this is a checkmark
|
||||
if(event.target.type == "checkbox"){
|
||||
//Use the .checked property instead of .value
|
||||
value = event.target.checked;
|
||||
}
|
||||
|
||||
//Create settings map
|
||||
const settingsMap = new Map([
|
||||
[key, value]
|
||||
]);
|
||||
|
||||
this.handleUpdate(await utils.ajax.setChannelSetting(this.channel, settingsMap), event.target, key);
|
||||
//Send update and collect results
|
||||
const update = await utils.ajax.setChannelSetting(this.channel, settingsMap);
|
||||
|
||||
//Handle update from server
|
||||
this.handleUpdate(update, event.target, key);
|
||||
}
|
||||
|
||||
handleUpdate(data, target, key){
|
||||
|
|
|
|||
Loading…
Reference in a new issue