Skip to content
Merged
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
5cbb9fc
Merge pull request #1 from disc-template/env-example
ethanpaneraa Feb 3, 2025
7fa9ca1
Implemented video API POST and GET routes
HareshWed Mar 4, 2025
4f133ff
Implemented resumable uploading
HareshWed Mar 8, 2025
a255552
Make it pretty?
HareshWed Mar 8, 2025
3a27df2
Make it pretty again?
HareshWed Mar 8, 2025
7cddc68
Make it pretty again? Please work
HareshWed Mar 8, 2025
1234fb2
Make it pretty!!!
HareshWed Mar 8, 2025
04c8843
This WILL work
HareshWed Mar 8, 2025
823bf8e
Update vercel.json
geperez8 Mar 8, 2025
d9f638a
Update vercel.json
geperez8 Mar 8, 2025
7ef88a1
Finished uploading, editing, getting courses with authorization check…
HareshWed Apr 2, 2025
ead240d
Merge branch 'feature/auth-backend' of https://github.com/disc-sweb/b…
HareshWed Apr 2, 2025
57a7dbe
Updates for Linter
geperez8 Apr 7, 2025
c25400a
Updates for Linter
geperez8 Apr 7, 2025
3d22dfd
Update supabase.js
geperez8 Apr 7, 2025
dce17bb
Changes for Vercel Deployment
geperez8 Apr 7, 2025
f50c37e
Update vercel.json
geperez8 Apr 7, 2025
97a4a84
Update vercel.json
geperez8 Apr 7, 2025
56d44b5
Update vercel.json
geperez8 Apr 7, 2025
3113de4
Changes by prettier
geperez8 Apr 7, 2025
5d6ef28
Merge pull request #1 from disc-sweb/feature/auth-backend
disc-sweb Apr 7, 2025
d7926f8
Update server.js
geperez8 Apr 7, 2025
473fbb9
Finished Stripe Integration for buy courses
HareshWed Apr 12, 2025
b3f8bf1
Merge pull request #3 from disc-sweb/feature/auth-backend
geperez8 Apr 12, 2025
caf3054
Added new fields to backend. Returned separate user courses and non u…
HareshWed Apr 19, 2025
4279375
Changed backend to return user and nonuser courses
HareshWed Apr 22, 2025
8b7edff
Trying to fix lint stuff
HareshWed Apr 22, 2025
b6a453d
Changed git ignore file
HareshWed Apr 22, 2025
66e74be
Fixed small errors with backend
HareshWed Apr 26, 2025
3315717
Merge pull request #4 from disc-sweb/feature/auth-backend
HareshWed Apr 26, 2025
b8993e2
Added video upload optimizations. Changed auth controller to return a…
HareshWed May 9, 2025
5cf831d
Merge pull request #5 from disc-sweb/feature/auth-backend
HareshWed May 10, 2025
2376e84
Changed file url bug for editting course
HareshWed May 11, 2025
78cb1a6
Allowed support for different course types
HareshWed May 12, 2025
3278a31
Removed video controller as it was not needed
HareshWed May 12, 2025
4d865b2
Put webhook endpoint in environment variable folder
HareshWed May 12, 2025
fdcbeb4
Fixed trimmed video bug
HareshWed May 13, 2025
270218b
Merge pull request #6 from disc-sweb/feature/auth-backend
HareshWed May 13, 2025
e4e0616
Migrated file uploading from cloudinary to cloudflare r2. Deleted fil…
HareshWed May 19, 2025
1faa187
Added timing report on backend for debugging
HareshWed May 19, 2025
76625f9
Returned whether user owns a course on backend
HareshWed May 20, 2025
cafa111
Made changes to R2 worker to handle range requessts
HareshWed May 22, 2025
7d564f5
Made changes to use buffer instead of file paths for video and image …
HareshWed May 23, 2025
50bde30
Trying to fix lint issues in r2 worker
HareshWed May 23, 2025
dd4cf92
Trying to fix lint errors
HareshWed May 23, 2025
f856d6b
Trying to fix lint errors
HareshWed May 23, 2025
f20de24
Trying to fix lint errors
HareshWed May 23, 2025
db39954
Trying to fix lint errors
HareshWed May 23, 2025
1d0af1c
Merge pull request #7 from disc-sweb/feature/auth-backend
HareshWed May 23, 2025
a7dc4ff
Fixed CORS issue with server
HareshWed May 23, 2025
69677f8
Merge pull request #8 from disc-sweb/feature/auth-backend
HareshWed May 23, 2025
22ada88
Problem was upload size. Not cors. Reversing previous change
HareshWed May 23, 2025
efd66fa
Added shorter trimmed video in order to meet vercel requirements
HareshWed May 24, 2025
5c53651
Merge pull request #9 from disc-sweb/feature/auth-backend
HareshWed May 24, 2025
6094a4f
Trying to fix ffmpeg problmen
HareshWed May 24, 2025
2549c03
Merge pull request #10 from disc-sweb/feature/auth-backend
HareshWed May 24, 2025
ea30ecc
Trying to fix ffmpeg deployment problem
HareshWed May 24, 2025
b90bc1e
Trying to fix ffmpeg deployment problem
HareshWed May 24, 2025
d6248c9
Trying to fix ffmpeg deployment problem
HareshWed May 24, 2025
31a0047
Installing ffmpeg package
HareshWed May 24, 2025
d973085
Trying to solve ffmpeg issues
HareshWed May 24, 2025
1807fd1
Trying to solve ffmpeg issues
HareshWed May 24, 2025
30bc90a
Reversing back to old version to fix errors on different branch
HareshWed May 24, 2025
83ff44f
Reversing back to old version to fix errors on different branch
HareshWed May 24, 2025
68baa1b
Using cloudinary for video trimming with unlimited free credits
HareshWed May 26, 2025
af5db4d
Merge branch 'main' into feature/auth-backend
HareshWed May 26, 2025
87cafbb
Updating editing trimming
HareshWed May 26, 2025
3475167
Merge branch 'feature/auth-backend' of https://github.com/disc-sweb/b…
HareshWed May 26, 2025
f4a7ac6
Reverting to old changes and deploying on Render
HareshWed May 26, 2025
70371f5
Reverting to old changes and deploying on Render
HareshWed May 26, 2025
10e2d9d
Reverting back to ffmpeg for test
HareshWed May 26, 2025
c8fff04
Fixing lint issues
HareshWed May 26, 2025
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
79 changes: 70 additions & 9 deletions src/controllers/courseController.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
const cloudinary = require('cloudinary').v2;
const supabase = require('../config/supabase');

const ffmpeg = require('fluent-ffmpeg');
const { Readable } = require('stream');

const STRIPE_API_KEY = process.env.STRIPE_API_KEY;
const stripe = require('stripe')(STRIPE_API_KEY);

const FRONTEND_URL = process.env.FRONTEND_URL;

const {
cloudflareUpload,
cloudflareDelete,
cloudinaryVideoUpload,
} = require('./fileUploader');
cloudinary.config({
secure: true,
});

const { cloudflareUpload, cloudflareDelete } = require('./fileUploader');

//Secret to use stripe webhook
const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET;
Expand Down Expand Up @@ -42,6 +46,43 @@ async function checkAdmin(req) {
return user.admin_access;
}

async function trimVideo(videoBuffer, mimeType) {
const startTime = '00:00:00';
const duration = 15; // seconds
const inputFormat = mimeType.split('/')[1];
const outputFormat = 'mp4';

return new Promise((resolve, reject) => {
// Turn the Buffer into a one-chunk Readable
const inputStream = Readable.from([videoBuffer]);

// collect the output
const chunks = [];
const command = ffmpeg(inputStream)
.inputFormat(inputFormat) // tell ffmpeg the incoming stream format
.setStartTime(startTime) // where to start
.setDuration(duration) // how long
.outputOptions([
'-movflags frag_keyframe+empty_moov', // allow streaming mp4
])
.format(outputFormat) // output format
.on('error', (err) => {
console.error('FFmpeg failed:', err);
reject(new Error('Video trimming failed.'));
});

// pipe stdout to our collector
const ffStream = command.pipe();

ffStream.on('data', (chunk) => chunks.push(chunk));
ffStream.on('end', () => resolve(Buffer.concat(chunks)));
ffStream.on('error', (err) => {
console.error('Stream error:', err);
reject(new Error('Error while streaming trimmed video.'));
});
});
}

async function deleteFiles(urls) {
for (const url of urls) {
if (url) {
Expand Down Expand Up @@ -114,7 +155,14 @@ const courseController = {
/\s+/g,
'-'
);
restricted_video_link = await cloudinaryVideoUpload(video_link, true);
const trimmedVideoBuffer = await trimVideo(videoBuffer, video.mimetype);
const restrictedResult = await cloudflareUpload(
videoFileName,
video.mimetype,
trimmedVideoBuffer
);
if (restrictedResult.error) throw new Error(restrictedResult.error);
restricted_video_link = restrictedResult.data.url;
timings.restrictedVideo = Date.now() - restrictedStartTime;
console.log(
`Restricted video upload took ${timings.restrictedVideo}ms`
Expand Down Expand Up @@ -287,13 +335,21 @@ const courseController = {
const videoBuffer = video.buffer;
console.log('Updating video...');
let videoFileName = null;
let restrictedFileName = null;

if (!currentCourse.video_link) {
// New Online course conversion
videoFileName = `video-${title}-${Date.now()}`.replace(/\s+/g, '-');
restrictedFileName = `restricted-${title}-${Date.now()}`.replace(
/\s+/g,
'-'
);
} else {
// Existing Online course update
videoFileName = currentCourse.video_link.split('/').pop();
restrictedFileName = currentCourse.restricted_video_link
.split('/')
.pop();
}

// Update existing files
Expand All @@ -305,10 +361,15 @@ const courseController = {
if (videoResult.error) throw new Error(videoResult.error);
updateObj.video_link = videoResult.data.url;

updateObj.restricted_video_link = await cloudinaryVideoUpload(
updateObj.video_link,
true
console.log('Updating restricted video...');
const trimmedVideoBuffer = await trimVideo(videoBuffer, video.mimetype);
const restrictedResult = await cloudflareUpload(
restrictedFileName,
video.mimetype,
trimmedVideoBuffer
);
if (restrictedResult.error) throw new Error(restrictedResult.error);
updateObj.restricted_video_link = restrictedResult.data.url;
}

// Handle image upload if provided
Expand Down