This project implements a dynamic file upload and serving mechanism based on the user's internet speed. It uses Node.js for the server-side logic and Angular for the client-side logic. The server utilizes speedtest-net to check the user's internet speed in real-time and express-fileupload for file uploads. Files are compressed using sharp and then uploaded to AWS S3 using the aws-sdk. The client-side logic determines the appropriate file version to serve based on the user's internet speed.
SHARP
for compress imagespeedtest-net
for realtime speed checkexpress-fileupload
aws-sdk
SHARP
for compress imagespeedtest-net
for realtime speed checkexpress-fileupload
aws-sdk
const speedTest = require('speedtest-net');
app.get('/internet-speed', async (req, res) => {
try {
const { speeds } = await speedTest();
// Convert speed to KBps
const speedKBps = Math.round(speeds.download / 1024);
res.json({ speed: speedKBps });
} catch (error) {
console.error(error);
res.status(500).json({ error: 'Failed to get internet speed' });
}
});
const express = require('express');
const fileUpload = require('express-fileupload');
const sharp = require('sharp');
const AWS = require('aws-sdk');
const app = express();
app.use(fileUpload());
// API endpoint to upload media file
app.post('/upload', async (req, res) => {
try {
const file = req.files.file;
const sizes = [20, 40, 60, 80, 100];
const versions = await Promise.all(sizes.map(async size => {
const resizedImage = await sharp(file.data)
.resize({ width: Math.floor(file.size * (size / 100)) })
.toBuffer();
const s3 = new AWS.S3({
accessKeyId: 'YOUR_ACCESS_KEY_ID',
secretAccessKey: 'YOUR_SECRET_ACCESS_KEY'
});
const params = {
Bucket: 'YOUR_BUCKET_NAME',
Key: `${file.name}_${size}.jpg`,
Body: resizedImage
};
await s3.upload(params).promise();
return `http://yourcdn.com/${file.name}_${size}.jpg`;
}));
res.json({ message: 'File uploaded successfully', versions });
} catch (error) {
console.error(error);
res.status(500).json({ error: 'Failed to upload file' });
}
});
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class InternetSpeedService {
constructor(private http: HttpClient) {}
getInternetSpeed(): Observable<number> {
return this.http.get<number>('http://your-node-server/internet-speed');
}
getMediaUrlBasedOnSpeed(url20: string, url40: string, url60: string, url80: string, url100: string): Observable<string> {
return new Observable(observer => {
this.getInternetSpeed().subscribe(speed => {
let selectedUrl: string;
if (speed < 50) { // less than 50 KBps
selectedUrl = url20;
} else if (speed < 200) { // between 50 and 200 KBps
selectedUrl = url40;
} else if (speed < 500) { // between 200 and 500 KBps
selectedUrl = url60;
} else if (speed < 1000) { // between 500 KBps and 1 MBps
selectedUrl = url80;
} else { // greater than 1 MBps
selectedUrl = url100;
}
observer.next(selectedUrl);
observer.complete();
});
});
}
}
- image-and-video-compressor
- Git hub repo
- This package wouldn't be possible without the following awesome libraries:
- sharp - High-performance Node.js image processing.
- fluent-ffmpeg - A fluent API to FFMPEG.
Sure! Here's a small README.md file you can add to your project to explain the video compression code and the codecs:
This Node.js script demonstrates how to compress a video file using FFmpeg with support for two different codecs: AV1 and H.264.
-
Install FFmpeg and FFmpeg utilities in your Node.js project:
npm install @ffmpeg/ffmpeg @ffmpeg/util
-
Run the Node.js script to compress videos using different codecs.
const { exec } = require('@ffmpeg/ffmpeg');
async function compressVideo(inputPath, outputPath, codec) {
try {
let codecFlag = '';
if (codec === 'av1') {
codecFlag = '-c:v libaom-av1 -strict experimental';
} else if (codec === 'h264') {
codecFlag = '-c:v libx264';
} else {
throw new Error('Unsupported codec. Supported codecs are "av1" and "h264".');
}
// Run FFmpeg command to compress video
await exec(`-i ${inputPath} -c:a copy ${codecFlag} ${outputPath}`);
console.log('Video compression successful!');
} catch (error) {
console.error('Error compressing video:', error);
}
}
// Example usage
const inputPath = 'path/to/input/video.mp4';
const av1OutputPath = 'path/to/output/compressed_video_av1.mp4';
const h264OutputPath = 'path/to/output/compressed_video_h264.mp4';
// Check if codec argument is provided
const codecArg = process.argv[2];
if (!codecArg) {
console.error('Please provide a codec argument. Usage: node compress_video.js <codec>');
process.exit(1);
}
// Compress video based on the codec argument
if (codecArg === 'av1') {
compressVideo(inputPath, av1OutputPath, 'av1');
} else if (codecArg === 'h264') {
compressVideo(inputPath, h264OutputPath, 'h264');
} else {
console.error('Unsupported codec. Supported codecs are "av1" and "h264".');
}
To compress a video using AV1 codec:
node compress_video.js av1
To compress a video using H.264 codec:
node compress_video.js h264
Replace inputPath
and outputPath
in the compressVideo
function with your desired input and output file paths.
-
AV1 (AOMedia Video 1): AV1 is a royalty-free video codec designed for video transmissions over the internet. It offers high compression efficiency and is supported by major browsers like Chrome and Firefox.
-
H.264 (Advanced Video Coding): H.264 is a widely used video codec for compressing and transmitting video streams over the internet. It provides good compression efficiency and is supported by most devices and browsers.
@ffmpeg/ffmpeg
: FFmpeg package for Node.js.@ffmpeg/util
: FFmpeg utilities for Node.js.
using sharp and speedtest-net for optimization and serve