
Recherche avancée
Médias (1)
-
SPIP - plugins - embed code - Exemple
2 septembre 2013, par
Mis à jour : Septembre 2013
Langue : français
Type : Image
Autres articles (63)
-
Personnaliser en ajoutant son logo, sa bannière ou son image de fond
5 septembre 2013, parCertains thèmes prennent en compte trois éléments de personnalisation : l’ajout d’un logo ; l’ajout d’une bannière l’ajout d’une image de fond ;
-
Publier sur MédiaSpip
13 juin 2013Puis-je poster des contenus à partir d’une tablette Ipad ?
Oui, si votre Médiaspip installé est à la version 0.2 ou supérieure. Contacter au besoin l’administrateur de votre MédiaSpip pour le savoir -
MediaSPIP v0.2
21 juin 2013, parMediaSPIP 0.2 is the first MediaSPIP stable release.
Its official release date is June 21, 2013 and is announced here.
The zip file provided here only contains the sources of MediaSPIP in its standalone version.
To get a working installation, you must manually install all-software dependencies on the server.
If you want to use this archive for an installation in "farm mode", you will also need to proceed to other manual (...)
Sur d’autres sites (7854)
-
Merge file without data loss using FFmpeg inside of WASM
9 septembre 2023, par DejiEdit : I'm rewriting this entire question


Goal : To reconstruct a video from its pieces/chunks from a network stream inside of an
@ffmpeg/ffmpeg
worker

Problems :


- 

- Video chunks/pieces which come after the first piece/chunk are reported by
@ffmpeg/ffmpeg
to have invalid data, as seen in the log below :




{
 "type": "stderr",
 "message": "video-0_chunk-1.part: Invalid data found when processing input"
}



- 

- How would I merge these chunks/pieces to reconstruct the full video using
@ffmpeg/ffmpeg
(after solving the first issue above)




My current code situation :


- 

- For merging the video pieces




const constructFile = async (chunks: Uint8Array[], queueId: number) => {
 await Promise.all(
 chunks.map(async (chunk, index) => {
 const chunkFile = `video-${queueId}_chunk-${index}`;
 await ffmpeg.writeFile(chunkFile, chunk);

 // Return information about newly created file
 ffmpeg.exec(["-i", chunkFile]);
 })
 );
};



I'm reading the logs/output for


ffmpeg.exec(['-i', chunkFile])



using


ffmpeg.on('log', (log) => console.log(log))



- 

- For fetching the videos using streams




await useFetch(Capacitor.convertFileSrc(file.path), {
 responseType: "stream",

 onResponse: async ({ response }) => {
 if (response.body) {
 const reader = response.body.getReader();

 while (true) {
 const { done, value } = await reader.read();

 if (done) break;
 file.chunks.push(value);
 }
 reader.releaseLock();
 }
 },
});



Note : file.chunks is linked to a reactive value which is passed to
constructFile()
when initialized

These are the logs I get from the code currently above :


chunk-4OF65L5M.js:2710 <suspense> is an experimental feature and its API will likely change.
(index):298 native App.addListener (#25407936)
(index):298 native FilePicker.pickVideos (#25407937)
(index):272 result FilePicker.pickVideos (#25407937)
(index):298 native VideoEditor.thumbnail (#25407938)
(index):272 result VideoEditor.thumbnail (#25407938)
Processing.vue:135 {type: 'stderr', message: 'ffmpeg version 5.1.3 Copyright (c) 2000-2022 the FFmpeg developers'}
Processing.vue:135 {type: 'stderr', message: ' built with emcc (Emscripten gcc/clang-like repla…3.1.40 (5c27e79dd0a9c4e27ef2326841698cdd4f6b5784)'}
Processing.vue:135 {type: 'stderr', message: ' configuration: --target-os=none --arch=x86_32 --…e-libfreetype --enable-libfribidi --enable-libass'}
Processing.vue:135 {type: 'stderr', message: ' libavutil 57. 28.100 / 57. 28.100'}
Processing.vue:135 {type: 'stderr', message: ' libavcodec 59. 37.100 / 59. 37.100'}
Processing.vue:135 {type: 'stderr', message: ' libavformat 59. 27.100 / 59. 27.100'}
Processing.vue:135 {type: 'stderr', message: ' libavdevice 59. 7.100 / 59. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libavfilter 8. 44.100 / 8. 44.100'}
Processing.vue:135 {type: 'stderr', message: ' libswscale 6. 7.100 / 6. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libswresample 4. 7.100 / 4. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libpostproc 56. 6.100 / 56. 6.100'}
Processing.vue:135 {type: 'stderr', message: "Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'video-0_chunk-0':"}
Processing.vue:135 {type: 'stderr', message: ' Metadata:'}
Processing.vue:135 {type: 'stderr', message: ' major_brand : mp42'}
Processing.vue:135 {type: 'stderr', message: ' minor_version : 0'}
Processing.vue:135 {type: 'stderr', message: ' compatible_brands: isommp42'}
Processing.vue:135 {type: 'stderr', message: ' creation_time : 2022-11-29T14:46:32.000000Z'}
Processing.vue:135 {type: 'stderr', message: ' Duration: 00:00:51.50, start: 0.000000, bitrate: 81 kb/s'}
Processing.vue:135 {type: 'stderr', message: ' Stream #0:0[0x1](und): Video: h264 (High) (avc1 …6], 259 kb/s, 30 fps, 30 tbr, 15360 tbn (default)'}
Processing.vue:135 {type: 'stderr', message: ' Metadata:'}
Processing.vue:135 {type: 'stderr', message: ' creation_time : 2022-11-29T14:46:32.000000Z'}
Processing.vue:135 {type: 'stderr', message: ' handler_name : ISO Media file produced by Google Inc. Created on: 11/29/2022.'}
Processing.vue:135 {type: 'stderr', message: ' vendor_id : [0][0][0][0]'}
Processing.vue:135 {type: 'stderr', message: ' Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0…706D), 44100 Hz, stereo, fltp, 127 kb/s (default)'}
Processing.vue:135 {type: 'stderr', message: ' Metadata:'}
Processing.vue:135 {type: 'stderr', message: ' creation_time : 2022-11-29T14:46:32.000000Z'}
Processing.vue:135 {type: 'stderr', message: ' handler_name : ISO Media file produced by Google Inc. Created on: 11/29/2022.'}
Processing.vue:135 {type: 'stderr', message: ' vendor_id : [0][0][0][0]'}
Processing.vue:135 {type: 'stderr', message: 'At least one output file must be specified'}
Processing.vue:135 {type: 'stderr', message: 'Aborted()'}
Processing.vue:135 {type: 'stderr', message: 'ffmpeg version 5.1.3 Copyright (c) 2000-2022 the FFmpeg developers'}
Processing.vue:135 {type: 'stderr', message: ' built with emcc (Emscripten gcc/clang-like repla…3.1.40 (5c27e79dd0a9c4e27ef2326841698cdd4f6b5784)'}
Processing.vue:135 {type: 'stderr', message: ' configuration: --target-os=none --arch=x86_32 --…e-libfreetype --enable-libfribidi --enable-libass'}
Processing.vue:135 {type: 'stderr', message: ' libavutil 57. 28.100 / 57. 28.100'}
Processing.vue:135 {type: 'stderr', message: ' libavcodec 59. 37.100 / 59. 37.100'}
Processing.vue:135 {type: 'stderr', message: ' libavformat 59. 27.100 / 59. 27.100'}
Processing.vue:135 {type: 'stderr', message: ' libavdevice 59. 7.100 / 59. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libavfilter 8. 44.100 / 8. 44.100'}
Processing.vue:135 {type: 'stderr', message: ' libswscale 6. 7.100 / 6. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libswresample 4. 7.100 / 4. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libpostproc 56. 6.100 / 56. 6.100'}
Processing.vue:135 {type: 'stderr', message: 'video-0_chunk-1: Invalid data found when processing input'}
Processing.vue:135 {type: 'stderr', message: 'Aborted()'}
Processing.vue:135 {type: 'stderr', message: 'ffmpeg version 5.1.3 Copyright (c) 2000-2022 the FFmpeg developers'}
Processing.vue:135 {type: 'stderr', message: ' built with emcc (Emscripten gcc/clang-like repla…3.1.40 (5c27e79dd0a9c4e27ef2326841698cdd4f6b5784)'}
Processing.vue:135 {type: 'stderr', message: ' configuration: --target-os=none --arch=x86_32 --…e-libfreetype --enable-libfribidi --enable-libass'}
Processing.vue:135 {type: 'stderr', message: ' libavutil 57. 28.100 / 57. 28.100'}
Processing.vue:135 {type: 'stderr', message: ' libavcodec 59. 37.100 / 59. 37.100'}
Processing.vue:135 {type: 'stderr', message: ' libavformat 59. 27.100 / 59. 27.100'}
Processing.vue:135 {type: 'stderr', message: ' libavdevice 59. 7.100 / 59. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libavfilter 8. 44.100 / 8. 44.100'}
Processing.vue:135 {type: 'stderr', message: ' libswscale 6. 7.100 / 6. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libswresample 4. 7.100 / 4. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libpostproc 56. 6.100 / 56. 6.100'}
Processing.vue:135 {type: 'stderr', message: 'video-0_chunk-2: Invalid data found when processing input'}
Processing.vue:135 {type: 'stderr', message: 'Aborted()'}
Processing.vue:135 {type: 'stderr', message: 'ffmpeg version 5.1.3 Copyright (c) 2000-2022 the FFmpeg developers'}
Processing.vue:135 {type: 'stderr', message: ' built with emcc (Emscripten gcc/clang-like repla…3.1.40 (5c27e79dd0a9c4e27ef2326841698cdd4f6b5784)'}
Processing.vue:135 {type: 'stderr', message: ' configuration: --target-os=none --arch=x86_32 --…e-libfreetype --enable-libfribidi --enable-libass'}
Processing.vue:135 {type: 'stderr', message: ' libavutil 57. 28.100 / 57. 28.100'}
Processing.vue:135 {type: 'stderr', message: ' libavcodec 59. 37.100 / 59. 37.100'}
Processing.vue:135 {type: 'stderr', message: ' libavformat 59. 27.100 / 59. 27.100'}
Processing.vue:135 {type: 'stderr', message: ' libavdevice 59. 7.100 / 59. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libavfilter 8. 44.100 / 8. 44.100'}
Processing.vue:135 {type: 'stderr', message: ' libswscale 6. 7.100 / 6. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libswresample 4. 7.100 / 4. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libpostproc 56. 6.100 / 56. 6.100'}
Processing.vue:135 {type: 'stderr', message: 'video-0_chunk-3: Invalid data found when processing input'}
Processing.vue:135 {type: 'stderr', message: 'Aborted()'}
Processing.vue:135 {type: 'stderr', message: 'ffmpeg version 5.1.3 Copyright (c) 2000-2022 the FFmpeg developers'}
Processing.vue:135 {type: 'stderr', message: ' built with emcc (Emscripten gcc/clang-like repla…3.1.40 (5c27e79dd0a9c4e27ef2326841698cdd4f6b5784)'}
Processing.vue:135 {type: 'stderr', message: ' configuration: --target-os=none --arch=x86_32 --…e-libfreetype --enable-libfribidi --enable-libass'}
Processing.vue:135 {type: 'stderr', message: ' libavutil 57. 28.100 / 57. 28.100'}
Processing.vue:135 {type: 'stderr', message: ' libavcodec 59. 37.100 / 59. 37.100'}
Processing.vue:135 {type: 'stderr', message: ' libavformat 59. 27.100 / 59. 27.100'}
Processing.vue:135 {type: 'stderr', message: ' libavdevice 59. 7.100 / 59. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libavfilter 8. 44.100 / 8. 44.100'}
Processing.vue:135 {type: 'stderr', message: ' libswscale 6. 7.100 / 6. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libswresample 4. 7.100 / 4. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libpostproc 56. 6.100 / 56. 6.100'}
Processing.vue:135 {type: 'stderr', message: 'video-0_chunk-4: Invalid data found when processing input'}
Processing.vue:135 {type: 'stderr', message: 'Aborted()'}
</suspense>


Notes :


- 

- The sections which start with
Processing.vue
come from the logging system I've setup. - The pieces/chunks gotten from the network where stored in exactly the same order in which they came
- If you've seen the old question, the
ReferenceError
happens as a result of HMR by Vite
- 

- Similar to this, some logs were repeated twice because I was actively changing some things and the component had to rerun from the start












Summary : If my problem is still not clear, you could provide another way of fetching a large file (video) from a network, loading the file into memory and passing the file data to
@ffmpeg/ffmpeg
for further processing

- Video chunks/pieces which come after the first piece/chunk are reported by
-
ffmpeg - allow to create empty aac file
27 juillet 2023, par user11149927I have two commands :


ffmpeg -y -i file.mp4 -vn -acodec copy file.aac



and then :


ffmpeg -y -i file.mp4 -i file.aac -c:v copy -c:a aac new-file.mp4



The first command throw error when the video has no audio :


Output file does not contain any stream



I would like to change first command to allow create empty aac file (maybe silent audio) when video has no audio. Or maybe exists better solution ?


-
Are there any alternatives to SharedArrayBuffer, or methods for video editing in a web browser ?
26 juillet 2023, par Govinda RegmiI'm working on a web-based video editing application using ffmeg that heavily relies on SharedArrayBuffer. Unfortunately, I've encountered a roadblock with the "Cross-Origin-Embedder-Policy : require-corp | credentialless" and "Cross-Origin-Opener-Policy : same-origin" headers. While these headers allow the usage of SharedArrayBuffer, they restrict other essential features, such as rendering images from an s3 bucket and script of TinyMce text editor.


I am trying to achieve
video editor like this


I am using "next" : "12.1.6" and
I tried to implement ffmeg like this :


import { useEffect, useState } from "react";

import { useDebounce } from "use-debounce";
import { createFFmpeg, fetchFile } from "@ffmpeg/ffmpeg";

import styles from "../videoEditor.module.scss";
import RangeInput from "../range-input/RangeInput";
import * as helpers from "../../../../utils/videoHelpers";

const FF = createFFmpeg({
 log: true,
 corePath: "https://unpkg.com/@ffmpeg/core@0.10.0/dist/ffmpeg-core.js",
});

(async function () {
 await FF.load();
})();

export const VideoTrimmer = ({
 videoFile,
 trimmedVideoFile,
 isConfirmClicked,
 setTrimmedVideoFile,
 onConfirmClickHandler,
}) => {
 const [URL, setURL] = useState([]);
 const [thumbNails, setThumbNails] = useState([]);
 const [videoMeta, setVideoMeta] = useState(null);
 const [inputVideoFile, setInputVideoFile] = useState(null);
 const [thumbnailIsProcessing, setThumbnailIsProcessing] = useState(false);

 const [rStart, setRstart] = useState(0);
 const [debouncedRstart] = useDebounce(rStart, 500);

 const [rEnd, setRend] = useState(10);
 const [debouncedRend] = useDebounce(rEnd, 500);

 const handleLoadedData = async (e) => {
 const el = e.target;
 const meta = {
 name: inputVideoFile.name,
 duration: el.duration,
 videoWidth: 50,
 videoHeight: 50,
 };
 setVideoMeta(meta);
 const thumbNails = await getThumbnails(meta);
 setThumbNails(thumbNails);
 };

 const getThumbnails = async ({ duration }) => {
 if (!FF.isLoaded()) await FF.load();
 setThumbnailIsProcessing(true);
 let MAX_NUMBER_OF_IMAGES = 15;
 let NUMBER_OF_IMAGES = duration < MAX_NUMBER_OF_IMAGES ? duration : 15;
 let offset =
 duration === MAX_NUMBER_OF_IMAGES ? 1 : duration / NUMBER_OF_IMAGES;

 const arrayOfImageURIs = [];
 FF.FS("writeFile", inputVideoFile.name, await fetchFile(inputVideoFile));

 for (let i = 0; i < NUMBER_OF_IMAGES; i++) {
 let startTimeInSecs = helpers.toTimeString(Math.round(i * offset));

 try {
 await FF.run(
 "-ss",
 startTimeInSecs,
 "-i",
 inputVideoFile.name,
 "-t",
 "00:00:1.000",
 "-vf",
 `scale=150:-1`,
 `img${i}.png`,
 );
 const data = FF.FS("readFile", `img${i}.png`);

 let blob = new Blob([data.buffer], { type: "image/png" });
 let dataURI = await helpers.readFileAsBase64(blob);
 FF.FS("unlink", `img${i}.png`);
 arrayOfImageURIs.push(dataURI);
 } catch (error) {
 // console.log({ message: error });
 }
 }
 setThumbnailIsProcessing(false);

 return arrayOfImageURIs;
 };
 const handleTrim = async () => {
 // setTrimIsProcessing(true);
 let startTime = ((rStart / 100) * videoMeta.duration).toFixed(2);
 let offset = ((rEnd / 100) * videoMeta.duration - startTime).toFixed(2);
 try {
 FF.FS("writeFile", inputVideoFile.name, await fetchFile(inputVideoFile));
 await FF.run(
 "-ss",
 helpers.toTimeString(startTime),
 "-i",
 inputVideoFile.name,
 "-t",
 helpers.toTimeString(offset),
 "-c",
 "copy",
 "ping.mp4",
 );
 const data = FF.FS("readFile", "ping.mp4");
 const dataURL = await helpers.readFileAsBase64(
 new Blob([data.buffer], { type: "video/mp4" }),
 );

 setTrimmedVideoFile(dataURL);
 } catch (error) {
 // console.log(error);
 } finally {
 // setTrimIsProcessing(false);
 }
 };

 const handleRangeChange = (type, event) => {
 const limit = parseInt((120 / videoMeta.duration) * 100);
 if (type === "start") {
 if (rEnd - rStart > limit) {
 setRend(parseInt(event.target.value) + limit);
 setRstart(parseInt(event.target.value));
 } else {
 setRstart(parseInt(event.target.value));
 }
 } else if (type === "end") {
 if (rEnd - rStart > limit) {
 setRstart(parseInt(event.target.value) - limit);
 setRend(parseInt(event.target.value));
 } else {
 setRend(parseInt(event.target.value));
 }
 }
 };

 useEffect(() => {
 if (videoMeta?.duration > 120) {
 const limit = parseInt((120 / videoMeta.duration) * 100);
 setRend(limit);
 }
 }, [videoMeta?.duration]);

 useEffect(() => {
 const videoFormData = new FormData();
 if (videoFile) {
 videoFormData.append("file", videoFile);
 const handleChange = async () => {
 setInputVideoFile(videoFile);
 setURL(await helpers.readFileAsBase64(videoFile));
 };
 handleChange();
 }
 }, []);

 useEffect(() => {
 if (videoMeta) {
 onConfirmClickHandler(handleTrim);
 }
 }, [isConfirmClicked]);

 useEffect(() => {
 if (debouncedRend == rEnd && debouncedRstart == rStart && videoMeta) {
 handleTrim();
 }
 }, [debouncedRend, debouncedRstart, videoMeta]);

 return (
 <>
 <article classname="grid_txt_2">
 
 {trimmedVideoFile ? (
 
 ) : (
 
 )}
 
 </article>
 
 >
 );
};



next.config.js


const nextConfig = {
 async headers() {
 return [
 {
 source: "/(.*)",
 headers: [
 { key: "Cross-Origin-Opener-Policy", value: "same-origin" },
 { key: "Cross-Origin-Embedder-Policy", value: "credentialless" },
 ],
 },
 ];
 },
 
};



This works seamlessly in Chrome and Edge, but it encounter issues (SharedArrayBuffer is not defined) in Firefox and Safari. How can we ensure it functions impeccably across all major browsers ?


When utilizing key : "Cross-Origin-Embedder-Policy", value : "require-corp" , I encounter an error while fetching images/scripts from cross-origin sources, resulting in "net::ERR_BLOCKED_BY_RESPONSE.NotSameOriginAfterDefaultedToSameOriginByCoep 200 (OK)". Cany you suggest me how can I resolve this issue ?