Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto change quality #341

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
e5c4ba9
added Resolution model
Yemeni Aug 23, 2020
db1cc56
Revert "added Resolution model"
Yemeni Aug 27, 2020
433b128
Merge branch 'master' into auto-change-quality
Yemeni Aug 27, 2020
6ee186a
added ffmpeg quality conversion to videos
Yemeni Aug 27, 2020
91819ef
added quality in upload model and made uploading push to mongodb
Yemeni Aug 28, 2020
753adb3
nasty stuff that are not checked yet
Yemeni Aug 28, 2020
e06f0fb
working example
mayeaux Aug 28, 2020
8199125
added loop over available video qualities
Yemeni Aug 29, 2020
892dc11
Added condition before converting qualities in upload
Yemeni Aug 31, 2020
aaa0f7d
Merge branch 'master' into auto-change-quality
Yemeni Sep 16, 2020
8f820b8
Merge branch 'master' into auto-change-quality
Yemeni Sep 16, 2020
5a3d80d
refactored coverting code + pending converts shows in media
Yemeni Sep 16, 2020
359359d
Removed extra spaces for eslint
Yemeni Sep 16, 2020
90adcd5
Update media.pug
Yemeni Sep 17, 2020
cb2a8d4
Merge branch 'master' into auto-change-quality
Yemeni Sep 19, 2020
a557926
Added bull and bull-board package
Yemeni Sep 19, 2020
711c50e
Added queue logic to converting
Yemeni Sep 19, 2020
77e89d2
Merge remote-tracking branch 'origin/auto-change-quality' into auto-c…
Yemeni Sep 19, 2020
c815416
added 480p video quality
Yemeni Sep 19, 2020
0a3b35a
added 480p video quality
Yemeni Sep 19, 2020
5d85a55
eslint removed unnecessary semi colon
Yemeni Sep 19, 2020
3511353
mark as complete and inform users that all video qualities are complete
Yemeni Sep 26, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 86 additions & 5 deletions controllers/backend/uploading.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const { b2, bucket, hostUrl } = require('../../lib/uploading/backblaze');
const ffmpegHelper = require('../../lib/uploading/ffmpeg');
const {
markUploadAsComplete,
markConvertAsComplete,
updateUsersUnreadSubscriptions,
runTimeoutFunction,
userCanUploadContentOfThisRating
Expand Down Expand Up @@ -534,7 +535,6 @@ exports.postFileUpload = async(req, res) => {
}

upload.fileType = 'video';

upload = await upload.save();
}

Expand All @@ -554,14 +554,95 @@ exports.postFileUpload = async(req, res) => {

uploadLogger.info('Upload marked as complete', logObject);

updateUsersUnreadSubscriptions(user);

uploadLogger.info('Updated subscribed users subscriptions', logObject);

if(!responseSent){
responseSent = true;
aboutToProcess(res, channelUrl, uniqueTag);
}
/*
all values in Kbps (kilobits per seconds)
2160p (4k) -> 13000
1440p 6000
1080p 3000
720p 2250
480p 500
360p 400
240p 300
144p 80

0-80 144p
81-299 360p
*/
// TODO: put qualities somewhere else
const qualities = [
{ name: '256 x 144p', quality: 144, bitrate: 80 },
{ name: '426 x 240p', quality: 240, bitrate: 300 },
{ name: '640 x 360p', quality: 360, bitrate: 400 },
{ name: '854 x 480p', quality: 480, bitrate: 500 },
{ name: '1280 x 720p', quality: 720, bitrate: 2250 }
];
// TODO: Do quality stuff
// TODO: loop quality stuff
// video will be available in original quality while this is happening in the background
// TODO: make a quality conversion counter/progress bar
for(var i = 0; i < qualities.length; i = i + 1){
if(bitrate >= qualities[i].bitrate){
// qualitySavePath = `${channelUrlFolder}/${uniqueTag}-${qualities[i].quality}.mp4`;

let qualityExists = upload.videoQualities.find(o => o.quality === qualities[i].quality);
if(!qualityExists){

upload.videoQualities.push({
quality: qualities[i].quality,
bitrate: qualities[i].bitrate,
fileSizeInMb: 1,
status: 'pending' // TODO: use enum here not string
});
}

}
}

await upload.save();

for(var i = 0; i < upload.videoQualities.length; i = i + 1){
if(bitrate >= upload.videoQualities[i].bitrate){
if(upload.videoQualities[i].status != 'complete'){
// TODO: this is kind of ugly lmao
qualitySavePath = `${channelUrlFolder}/${uniqueTag}-${upload.videoQualities[i].quality}.mp4`;

upload.videoQualities[i].status = 'converting';
// upload.videoQualities
await upload.save();
// await upload.save();
await ffmpegHelper.convertVideo({
uploadedPath: fileInDirectory,
title,
bitrate: upload.videoQualities[i].bitrate,
savePath: qualitySavePath,
uniqueTag: uniqueTag + '-' + upload.videoQualities[i].quality,
quality: upload.videoQualities[i].quality
});

upload.videoQualities[i].status = 'complete';
}

await upload.save();
}
// else {
// // do max possible conversion with the biggest bitrate left? then break;
// break;
// }

}

await markConvertAsComplete(uniqueTag, channelUrl, user);

uploadLogger.info('Quality all qualities are converted', logObject);

updateUsersUnreadSubscriptions(user);

uploadLogger.info('Updated subscribed users subscriptions', logObject);

});

// });
Expand Down
3 changes: 0 additions & 3 deletions controllers/frontend/public.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ exports.index = async(req, res) => {
}
};


/**
* GET /landing
* Landing page
Expand Down Expand Up @@ -117,7 +116,6 @@ exports.getLandingPage = async(req, res) => {
}
};


/**
* GET /globe
* Globe page.
Expand Down Expand Up @@ -232,7 +230,6 @@ exports.getDocs = async(req, res) => {
});
};


/**
* GET /donate
* Donation page
Expand Down
7 changes: 5 additions & 2 deletions lib/uploading/ffmpeg.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ function setRedisClient({ currentSeconds, uniqueTag, progress, force }){

// setRedisClient();

function convertVideo({ uploadedPath, title, bitrate, savePath, uniqueTag }){
function convertVideo({ uploadedPath, title, quality, bitrate, savePath, uniqueTag }){
return new Promise(function(resolve, reject) {

let command;
Expand All @@ -88,9 +88,12 @@ function convertVideo({ uploadedPath, title, bitrate, savePath, uniqueTag }){
command = ffmpeg(uploadedPath).videoCodec('libx264').audioCodec('aac').format('mp4')
.outputOptions([ '-preset faster', '-b:v 2500k' ]);

} else {
} else if(!quality){
command = ffmpeg(uploadedPath).videoCodec('libx264').audioCodec('aac').format('mp4')

} else{
command = ffmpeg(uploadedPath).videoCodec('libx264').audioCodec('aac').format('mp4')
.outputOptions([ '-preset faster', '-b:v ' + bitrate + 'k', '-vf scale=-2:' + quality ]);
}

let secondCounter = 0;
Expand Down
16 changes: 16 additions & 0 deletions lib/uploading/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,21 @@ async function markUploadAsComplete(uniqueTag, channelUrl, user, res){
return 'success'
}

async function markConvertAsComplete(uniqueTag, channelUrl, user, res){
// upload = await Upload.findOne({ uniqueTag });
// upload.status = 'completed';

// upload.processingCompletedAt = new Date();

// await upload.save();
console.log("quality converted")

// user.uploads.push(upload._id);
// await user.save();

return 'success'
}

async function updateUsersUnreadSubscriptions(user){
const subscriptions = await Subscription.find({ subscribedToUser: user._id, active: true });

Expand Down Expand Up @@ -84,6 +99,7 @@ const bytesToGb = (bytes, decimalPlaces = 4) => {

module.exports = {
markUploadAsComplete,
markConvertAsComplete,
updateUsersUnreadSubscriptions,
runTimeoutFunction,
userCanUploadContentOfThisRating,
Expand Down
9 changes: 9 additions & 0 deletions models/Upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@ const uploadSchema = new mongoose.Schema({
originalFileSizeInMb: Number,
processedFileSizeInMb: Number,
fileSize: Number, // TODO: should support highQualityFileSize as well for compressions

videoQualities: [
{
quality: 'String',
fileSizeInMb: Number,
bitrate: Number,
status: {type: String, enum: ['pending', 'converting', 'complete'], default: 'pending'}
}
],
bitrateInKbps: Number,
dimensions: {
height: String,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "NodeTube",
"version": "1.0.0",
"version": "1.0.3",
"description": "Video, audio and image hosting",
"repository": {
"type": "git",
Expand Down
1 change: 0 additions & 1 deletion routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@ function frontendRoutes(app){
app.get('/about', publicController.about);
app.get('/docs', publicController.getDocs);


app.get('/donate', publicController.getDonate);

app.get('/landing', publicController.getLandingPage);
Expand Down
28 changes: 21 additions & 7 deletions views/media.pug
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,17 @@ block content
h4.fw(style="font-size:22px;margin-top:30px;") If your upload is stuck on processing, let an admin know via the social links at the bottom of the page and we'll take a look.


if upload.status !== 'processing'

div(style="max-width:443px;margin:0 auto;")
//if(upload.videoQualities.includes({status: 'pending'}))
// h2.fw wtf
each val in upload.videoQualities
if val.status !== 'complete'
h4.fw(style="font-size:22px;margin-top:30px;") Video #{val.quality} convert is #{val.status}



<!-- DISPLAYING CONTENT -->
br
br
Expand All @@ -291,10 +302,13 @@ block content
div.display-div.magnetic(style="min-width:50%;min-height:50%;margin:0 auto;margin-top: -25px;")
// margin-top:46px;

video#media_player.display-element(playsinline poster=`${uploadServer}/${upload.uploader.channelUrl}/${upload.thumbnails.generated || upload.thumbnails.medium}` controls='', style="max-width:100%;background-color:black;")
video#media_player.display-element(playsfinline poster=`${uploadServer}/${upload.uploader.channelUrl}/${upload.thumbnails.generated || upload.thumbnails.medium}` controls='', style="max-width:100%;background-color:black;")
Yemeni marked this conversation as resolved.
Show resolved Hide resolved
// to
source.video-source(src=`${serverToUse}/${upload.uploader.channelUrl}/${upload.uniqueTag}.mp4`, type='video/mp4')
//source(src=upload.uploadUrl, type='video/mp4')
each val in upload.videoQualities
if val.status === 'complete'
source(src=`${serverToUse}/${upload.uploader.channelUrl}/${upload.uniqueTag}-${val.quality}.mp4`, size=`${val.quality}`, type='video/mp4')
//source.video-source(src=`${serverToUse}/${upload.uploader.channelUrl}/${upload.uniqueTag}.mp4`, type='video/mp4')
//source(src=upload.uploadUrl, type='video/mp4')

// if it's an audio
else if upload.fileType === 'audio'
Expand Down Expand Up @@ -898,7 +912,7 @@ block extra_footer_js
if upload.status == 'processing'
include ./mediaPlayerPartials/progressTrackerJs


// include the stuff of media to calculate converstion percentage

script(src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js")
script(src="https://cdnjs.cloudflare.com/ajax/libs/plyr/3.5.10/plyr.min.js")
Expand Down Expand Up @@ -1176,9 +1190,9 @@ block extra_footer_js

include ./mediaPlayerPartials/reportUploadFunctionalityJs

include ./mediaPlayerPartials/changeQualityJs

include ./mediaPlayerPartials/changeUserDefaultQualityJs
//include ./mediaPlayerPartials/changeQualityJs
//
//include ./mediaPlayerPartials/changeUserDefaultQualityJs

include mediaPlayerPartials/creditFunctionalityJs

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ script.
autoplay,
clickToPlay: true,
speed: {selected: 1, options: [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2]},
quality: { default: 144, options: [1080, 720 ,360, 240, 144] },
controls: ['play-large', 'play','progress', 'current-time', 'duration', 'rewind', 'fast-forward', 'mute', 'volume', 'settings', 'fullscreen'],
settings: ['speed', 'captions', 'quality', 'loop']
};
Expand Down