
Recherche avancée
Autres articles (91)
-
Use, discuss, criticize
13 avril 2011, parTalk to people directly involved in MediaSPIP’s development, or to people around you who could use MediaSPIP to share, enhance or develop their creative projects.
The bigger the community, the more MediaSPIP’s potential will be explored and the faster the software will evolve.
A discussion list is available for all exchanges between users. -
Le profil des utilisateurs
12 avril 2011, parChaque utilisateur dispose d’une page de profil lui permettant de modifier ses informations personnelle. Dans le menu de haut de page par défaut, un élément de menu est automatiquement créé à l’initialisation de MediaSPIP, visible uniquement si le visiteur est identifié sur le site.
L’utilisateur a accès à la modification de profil depuis sa page auteur, un lien dans la navigation "Modifier votre profil" est (...) -
Les tâches Cron régulières de la ferme
1er décembre 2010, parLa gestion de la ferme passe par l’exécution à intervalle régulier de plusieurs tâches répétitives dites Cron.
Le super Cron (gestion_mutu_super_cron)
Cette tâche, planifiée chaque minute, a pour simple effet d’appeler le Cron de l’ensemble des instances de la mutualisation régulièrement. Couplée avec un Cron système sur le site central de la mutualisation, cela permet de simplement générer des visites régulières sur les différents sites et éviter que les tâches des sites peu visités soient trop (...)
Sur d’autres sites (10438)
-
Revision 36317 : Il y a certains cas où l’on ne peut pas passer par revision_mot notamment ...
16 mars 2010, par kent1@… — LogIl y a certains cas où l’on ne peut pas passer par revision_mot notamment si on s’insère dans un formulaire d’édition d’article dans un pipeline pre_edition ... On ne passe pas la gestion des conflits dans ce cas là
-
Video streamign with FFMpeg and Nest.js+Next.js
17 septembre 2024, par AizenHere is my problem : I have one video src 1080p (on the frontend). On the frontend, I send this video-route to the backend :


const req = async()=>{try{const res = await axios.get('/catalog/item',{params:{SeriesName:seriesName}});return {data:res.data};}catch(err){console.log(err);return false;}}const fetchedData = await req();-On the backend i return seriesName.Now i can make a full path,what the video is,and where it is,code:



const videoUrl = 'C:/Users/arMori/Desktop/RedditClone/reddit/public/videos';console.log('IT VideoURL',videoUrl);



const selectedFile = `${videoUrl}/${fetchedData.data.VideoSource}/${seriesName}-1080p.mp4`
console.log(`ITS'S SELECTED FILE: ${selectedFile}`);



Ok, I have my src 1080p, now is the time to send it to the backend :


const response = await axios.post('/videoFormat', {videoUrl:selectedFile})console.log('Это консоль лог путей: ',response.data);const videoPaths = response.data;



Backend takes it and FFMpqg makes two types of resolution,720p and 480p,save it to the temp storage on backend, and then returns two routes where these videos stores


async videoUpload(videoUrl:string){try{const tempDir = C:/Users/arMori/Desktop/RedditClone/reddit_back/src/video/temp;const inputFile = videoUrl;console.log('VIDEOURL: ',videoUrl);



const outputFiles = [];
 
 await this.createDirectories(tempDir); 
 outputFiles.push(await this.convertVideo(inputFile, '1280x720', '720p.mp4'));
 outputFiles.push(await this.convertVideo(inputFile, '854x480', '480p.mp4'));
 console.log('OUTUPT FILES SERVICE: ',outputFiles);
 
 return outputFiles;

 }catch(err){
 console.error('VideoFormatterService Error: ',err);
 
 }
}

private convertVideo(inputPath:string,resolution:string,outputFileName:string):Promise<string>{
 const temp = `C:/Users/arMori/Desktop/RedditClone/reddit_back/src/video/temp`;
 return new Promise(async(resolve,reject)=>{
 const height = resolution.split('x')[1];
 console.log('HIEGHT: ',height);
 
 const outputDir = `C:/Users/arMori/Desktop/RedditClone/reddit_back/src/video/temp/${height}p`;
 const outputPath = join(outputDir, outputFileName);
 const isExists = await fs.access(outputPath).then(() => true).catch(() => false);
 if(isExists){ 
 console.log(`File already exists: ${outputPath}`);
 return resolve(outputPath)
 };
 ffmpeg(inputPath)
 .size(`${resolution}`)
 .videoCodec('libx264') // Кодек H.264
 .audioCodec('aac') 
 .output(outputPath)
 .on('end',()=>resolve(outputPath))
 .on('error',(err)=>reject(err))
 .run()
 
 })
}

private async createDirectories(temp:string){
 try{
 const dir720p = `${temp}/720p`;
 const dir480p = `${temp}/480p`;
 const dir720pExists = await fs.access(dir720p).then(() => true).catch(() => false);
 const dir480pExists = await fs.access(dir480p).then(() => true).catch(() => false);
 if(dir720pExists && dir480pExists){
 console.log('FILES ALIVE');
 return;
 }
 if (!dir720pExists) {
 await fs.mkdir(dir720p, { recursive: true });
 console.log('Папка 720p создана');
 }
 
 if (!dir480pExists) {
 await fs.mkdir(dir480p, { recursive: true });
 console.log('Папка 480p создана');
 }
 } catch (err) {
 console.error('Ошибка при создании директорий:', err);
 }
}
</string>


Continue frontentd code :


let videoPath;

if (quality === '720p') {
 videoPath = videoPaths[0];
} else if (quality === '480p') {
 videoPath = videoPaths[1];
}

if (!videoPath) {
 console.error('Video path not found!');
 return;
}

// Получаем видео по его пути
console.log('VIDEOPATH LOG: ',videoPath);
 
const videoRes = await axios.get('/videoFormat/getVideo', { 
 params: { path: videoPath } ,
 headers: { Range: 'bytes=0-' },
 responseType: 'blob'
 });
 console.log('Video fetched: ', videoRes);
 const videoBlob = new Blob([videoRes.data], { type: 'video/mp4' });
 const videoURL = URL.createObjectURL(videoBlob);
 return videoURL;
 /* console.log('Видео успешно загружено:', response.data); */
 } catch (error) {
 console.error('Ошибка при загрузке видео:', error);
 }
}



Here I just choose one of the route and make a new GET request (VideoRes), now in the controller in the backend, I'm trying to do a video streaming :


@Public()
 @Get('/getVideo')
 async getVideo(@Query('path') videoPath:string,@Req() req:Request,@Res() res:Response){
 try {
 console.log('PATH ARGUMENT: ',videoPath);
 console.log('VIDEOPATH IN SERVICE: ',videoPath);
 const videoSize = (await fs.stat(videoPath)).size;
 const CHUNK_SIZE = 10 ** 6;
 const range = req.headers['range'] as string | undefined;
 if (!range) {
 return new ForbiddenException('Range не найденно');
 }
 const start = Number(range.replace(/\D/g,""));
 const end = Math.min(start + CHUNK_SIZE,videoSize - 1);

 const contentLength = end - start + 1;
 const videoStream = fsSync.createReadStream(videoPath, { start, end });
 const headers = {
 'Content-Range':`bytes ${start}-${end}/${videoSize}`,
 'Accept-Ranges':'bytes',
 'Content-Length':contentLength,
 'Content-Type':'video/mp4'
 }
 
 res.writeHead(206,headers);

 // Передаем поток в ответ
 videoStream.pipe(res);
 

 // Если возникнет ошибка при стриминге, логируем ошибку
 videoStream.on('error', (error) => {
 console.error('Ошибка при чтении видео:', error);
 res.status(500).send('Ошибка при чтении видео');
 });
 } catch (error) {
 console.error('Ошибка при обработке запросов:', error);
 return res.status(400).json({ message: 'Ошибка при обработке getVideo запросов' });
 }
 }



Send to the frontend


res.writeHead(206,headers);



In the frontend, I make blob url for video src and return it


const videoBlob = new Blob([videoRes.data], { type: 'video/mp4' });const videoURL = URL.createObjectURL(videoBlob);return videoURL;



And assign src to the video :


useVideo(seriesName,quality).then(src => {
 if (src) {
 console.log('ITS VIDEOLOGISC GOIDA!');
 if(!playRef.current) return;
 
 const oldURL = playRef.current.src;
 if (oldURL && oldURL.startsWith('blob:')) {
 URL.revokeObjectURL(oldURL);
 }
 playRef.current.pause();
 playRef.current.src = '';
 setQuality(quality);
 console.log('SRC: ',src);
 
 playRef.current.src = src;
 playRef.current.load();
 console.log('ITS VIDEOURL GOIDA!');
 togglePlayPause();
 }
 })
 .catch(err => console.error('Failed to fetch video', err));



But the problem is :




Vinland-Saga:1 Uncaught (in promise) NotSupportedError : Failed to load because no supported source was found




And I don't know why...


I tried everything, but I don't understand why src is incorrect..


-
Video streaming error : Uncaught (in promise) NotSupportedError : Failed to load because no supported source was found
18 septembre 2024, par AizenHere is my problem : I have one video src 1080p (on the frontend). On the frontend, I send this video-route to the backend :


const req = async()=>{try{const res = await axios.get('/catalog/item',{params:{SeriesName:seriesName}});return {data:res.data};}catch(err){console.log(err);return false;}}const fetchedData = await req();-On the backend i return seriesName.Now i can make a full path,what the video is,and where it is,code:



const videoUrl = 'C:/Users/arMori/Desktop/RedditClone/reddit/public/videos';console.log('IT VideoURL',videoUrl);



const selectedFile = `${videoUrl}/${fetchedData.data.VideoSource}/${seriesName}-1080p.mp4`
console.log(`ITS'S SELECTED FILE: ${selectedFile}`);



Ok, I have my src 1080p, now is the time to send it to the backend :


const response = await axios.post('/videoFormat', {videoUrl:selectedFile})console.log('Это консоль лог путей: ',response.data);const videoPaths = response.data;



Backend takes it and FFMpqg makes two types of resolution,720p and 480p,save it to the temp storage on backend, and then returns two routes where these videos stores


async videoUpload(videoUrl:string){try{const tempDir = C:/Users/arMori/Desktop/RedditClone/reddit_back/src/video/temp;const inputFile = videoUrl;console.log('VIDEOURL: ',videoUrl);



const outputFiles = [];
 
 await this.createDirectories(tempDir); 
 outputFiles.push(await this.convertVideo(inputFile, '1280x720', '720p.mp4'));
 outputFiles.push(await this.convertVideo(inputFile, '854x480', '480p.mp4'));
 console.log('OUTUPT FILES SERVICE: ',outputFiles);
 
 return outputFiles;

 }catch(err){
 console.error('VideoFormatterService Error: ',err);
 
 }
}

private convertVideo(inputPath:string,resolution:string,outputFileName:string):Promise<string>{
 const temp = `C:/Users/arMori/Desktop/RedditClone/reddit_back/src/video/temp`;
 return new Promise(async(resolve,reject)=>{
 const height = resolution.split('x')[1];
 console.log('HIEGHT: ',height);
 
 const outputDir = `C:/Users/arMori/Desktop/RedditClone/reddit_back/src/video/temp/${height}p`;
 const outputPath = join(outputDir, outputFileName);
 const isExists = await fs.access(outputPath).then(() => true).catch(() => false);
 if(isExists){ 
 console.log(`File already exists: ${outputPath}`);
 return resolve(outputPath)
 };
 ffmpeg(inputPath)
 .size(`${resolution}`)
 .videoCodec('libx264') // Кодек H.264
 .audioCodec('aac') 
 .output(outputPath)
 .on('end',()=>resolve(outputPath))
 .on('error',(err)=>reject(err))
 .run()
 
 })
}

private async createDirectories(temp:string){
 try{
 const dir720p = `${temp}/720p`;
 const dir480p = `${temp}/480p`;
 const dir720pExists = await fs.access(dir720p).then(() => true).catch(() => false);
 const dir480pExists = await fs.access(dir480p).then(() => true).catch(() => false);
 if(dir720pExists && dir480pExists){
 console.log('FILES ALIVE');
 return;
 }
 if (!dir720pExists) {
 await fs.mkdir(dir720p, { recursive: true });
 console.log('Папка 720p создана');
 }
 
 if (!dir480pExists) {
 await fs.mkdir(dir480p, { recursive: true });
 console.log('Папка 480p создана');
 }
 } catch (err) {
 console.error('Ошибка при создании директорий:', err);
 }
}
</string>


Continue frontentd code :


let videoPath;

if (quality === '720p') {
 videoPath = videoPaths[0];
} else if (quality === '480p') {
 videoPath = videoPaths[1];
}

if (!videoPath) {
 console.error('Video path not found!');
 return;
}

// Получаем видео по его пути
console.log('VIDEOPATH LOG: ',videoPath);
 
const videoRes = await axios.get('/videoFormat/getVideo', { 
 params: { path: videoPath } ,
 headers: { Range: 'bytes=0-' },
 responseType: 'blob'
 });
 console.log('Video fetched: ', videoRes);
 const videoBlob = new Blob([videoRes.data], { type: 'video/mp4' });
 const videoURL = URL.createObjectURL(videoBlob);
 return videoURL;
 /* console.log('Видео успешно загружено:', response.data); */
 } catch (error) {
 console.error('Ошибка при загрузке видео:', error);
 }
}



Here I just choose one of the route and make a new GET request (VideoRes), now in the controller in the backend, I'm trying to do a video streaming :


@Public()
 @Get('/getVideo')
 async getVideo(@Query('path') videoPath:string,@Req() req:Request,@Res() res:Response){
 try {
 console.log('PATH ARGUMENT: ',videoPath);
 console.log('VIDEOPATH IN SERVICE: ',videoPath);
 const videoSize = (await fs.stat(videoPath)).size;
 const CHUNK_SIZE = 10 ** 6;
 const range = req.headers['range'] as string | undefined;
 if (!range) {
 return new ForbiddenException('Range не найденно');
 }
 const start = Number(range.replace(/\D/g,""));
 const end = Math.min(start + CHUNK_SIZE,videoSize - 1);

 const contentLength = end - start + 1;
 const videoStream = fsSync.createReadStream(videoPath, { start, end });
 const headers = {
 'Content-Range':`bytes ${start}-${end}/${videoSize}`,
 'Accept-Ranges':'bytes',
 'Content-Length':contentLength,
 'Content-Type':'video/mp4'
 }
 
 res.writeHead(206,headers);

 // Передаем поток в ответ
 videoStream.pipe(res);
 

 // Если возникнет ошибка при стриминге, логируем ошибку
 videoStream.on('error', (error) => {
 console.error('Ошибка при чтении видео:', error);
 res.status(500).send('Ошибка при чтении видео');
 });
 } catch (error) {
 console.error('Ошибка при обработке запросов:', error);
 return res.status(400).json({ message: 'Ошибка при обработке getVideo запросов' });
 }
 }



Send to the frontend


res.writeHead(206,headers);



In the frontend, I make blob url for video src and return it


const videoBlob = new Blob([videoRes.data], { type: 'video/mp4' });const videoURL = URL.createObjectURL(videoBlob);return videoURL;



And assign src to the video :


useVideo(seriesName,quality).then(src => {
 if (src) {
 console.log('ITS VIDEOLOGISC GOIDA!');
 if(!playRef.current) return;
 
 const oldURL = playRef.current.src;
 if (oldURL && oldURL.startsWith('blob:')) {
 URL.revokeObjectURL(oldURL);
 }
 playRef.current.pause();
 playRef.current.src = '';
 setQuality(quality);
 console.log('SRC: ',src);
 
 playRef.current.src = src;
 playRef.current.load();
 console.log('ITS VIDEOURL GOIDA!');
 togglePlayPause();
 }
 })
 .catch(err => console.error('Failed to fetch video', err));



But the problem is :




Vinland-Saga:1 Uncaught (in promise) NotSupportedError : Failed to load because no supported source was found




And I don't know why...


I tried everything, but I don't understand why src is incorrect..