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.
add ffmpeg.wasm for video compressing using latest and very efficient technology using code av1 and h.264 which used by microsoft meta and many more giant companies for streaming videos real time.