Recherche avancée

Médias (91)

Autres articles (67)

  • Gestion des droits de création et d’édition des objets

    8 février 2011, par

    Par défaut, beaucoup de fonctionnalités sont limitées aux administrateurs mais restent configurables indépendamment pour modifier leur statut minimal d’utilisation notamment : la rédaction de contenus sur le site modifiables dans la gestion des templates de formulaires ; l’ajout de notes aux articles ; l’ajout de légendes et d’annotations sur les images ;

  • Dépôt de média et thèmes par FTP

    31 mai 2013, par

    L’outil MédiaSPIP traite aussi les média transférés par la voie FTP. Si vous préférez déposer par cette voie, récupérez les identifiants d’accès vers votre site MédiaSPIP et utilisez votre client FTP favori.
    Vous trouverez dès le départ les dossiers suivants dans votre espace FTP : config/ : dossier de configuration du site IMG/ : dossier des média déjà traités et en ligne sur le site local/ : répertoire cache du site web themes/ : les thèmes ou les feuilles de style personnalisées tmp/ : dossier de travail (...)

  • Keeping control of your media in your hands

    13 avril 2011, par

    The vocabulary used on this site and around MediaSPIP in general, aims to avoid reference to Web 2.0 and the companies that profit from media-sharing.
    While using MediaSPIP, you are invited to avoid using words like "Brand", "Cloud" and "Market".
    MediaSPIP is designed to facilitate the sharing of creative media online, while allowing authors to retain complete control of their work.
    MediaSPIP aims to be accessible to as many people as possible and development is based on expanding the (...)

Sur d’autres sites (9540)

  • Piwik analytics database : migrating from MySQL to MariaDB

    11 novembre 2015, par Piwik Core Team — Meta

    This short blog post is an announcement regarding the Piwik technology stack.

    Piwik compatible with MySQL and MariaDB

    Since our first public release Piwik uses the open source database server MySQL to store the analytics data.

    Piwik is also compatible with MariaDB. MariaDB is an enhanced, drop-in replacement for MySQL.

    Upgrading to MariaDB

    Many users from our community as well as Piwik Scalability Experts have confirmed that using MariaDB for Piwik has several advantages. MariaDB has in some cases significantly improved query performance and reliability of Piwik. Because MariaDB 5.5 is a complete drop-in-replacement for MySQL 5.5, upgrading can be as easy as running apt-get install mariadb-server (or equivalent for your platform). Existing third party techologies such as TokuDB (FAQ) and Galera are fully compatible with MariaDB.

    Learn more about upgrading to MariaDB : Upgrading from MySQL to MariaDB

    In the future, Piwik will stay compatible with both MySQL and MariaDB.

  • How to convert to QString from const char* result from ffmpeg C function

    18 octobre 2022, par Lucas

    I use the ffmpeg library in c++ / qt project

    


    extern "C" {&#xA;    #include <libavformat></libavformat>avformat.h>&#xA;    #include <libavutil></libavutil>dict.h>&#xA;}&#xA;

    &#xA;

    With this I read the media metadata from a local music file. This works quite fine :

    &#xA;

    avformat_open_input(&amp;format_song, path, NULL, NULL);&#xA;&#xA;while((tag = av_dict_get(format_song->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))){&#xA;                std::cout &lt;&lt; tag.key &lt;&lt; tag.value &lt;&lt; std::endl;&#xA;                // tag.value is a const char* (but in C!?)&#xA;}&#xA;

    &#xA;

    Altough the encoding of the tag.value seems to be different for files (maybe saved different in the id3tags). Here are some examples of different title values for different files :

    &#xA;

    "T&#xC3;&#xB6;hne" [&#xF6;]&#xA;"Die &#xC3;„rzte" [&#xC4;]&#xA;"F&#xFC;r Immer"&#xA;

    &#xA;

    How to convert this to a readable QString ?

    &#xA;

    There are some problems with the encoding of special characters. For most cases the following works :

    &#xA;

    QString result = QString(tag->value).normalized(QString::NormalizationForm_C);&#xA;//or:&#xA;QString result = QString::fromUtf8(tag->value);&#xA;

    &#xA;

    But sometimes this results in a U+FFFD � REPLACEMENT CHARACTER for some "Ü" "Ä" "ß" etc. chars.&#xA;But in in that cases fromLocal8Bit works. So I end up testing for replacement characters and choose a different conversion :

    &#xA;

    if(result.contains(QChar::ReplacementCharacter)){&#xA;      result = QString::fromLocal8Bit(tag->value);&#xA;}&#xA;

    &#xA;

    I expect there is a better way to do this ?

    &#xA;

  • How to set up my complex filter with zoompan and xfade for ffmpeg using Fluent-FFmpeg .complexFilter method ?

    21 août 2024, par Rémy Groleau

    I'm using fluent-ffmpeg with Node.js. My problem is the setup of my complex filter.

    &#xA;

    const filters = Array.from({ length: imageCount - 1 }).map((_, i) => {&#xA;        const rndInt = Math.floor(Math.random() * 1000) &#x2B; 1&#xA;&#xA;        return {&#xA;            zoompanFilter1: {&#xA;                filter: &#x27;zoompan&#x27;,&#xA;                options: {&#xA;                    z: &#x27;min(zoom&#x2B;0.001,1.3)&#x27;,&#xA;                    d: `${imageDuration * 60}`, &#xA;                    x: `iw/2-iw*(1/2-${rndInt}/100)*iw/zoom`, &#xA;                    y: `ih/2-ih*(1/2-${rndInt}/100)*ih/zoom`, &#xA;                    s: &#x27;1080x1920&#x27;, // Output size&#xA;                    fps: &#x27;60&#x27;&#xA;                },&#xA;                inputs: `[${i}:v]`,&#xA;                outputs: `zoomed${i}`&#xA;            },&#xA;            zoompanFilter2: {&#xA;                filter: &#x27;zoompan&#x27;,&#xA;                options: {&#xA;                    z: &#x27;min(zoom&#x2B;0.001,1.3)&#x27;, &#xA;                    d: `${imageDuration * 60}`, &#xA;                    x: &#x27;iw/2-iw*(1/2-33/100)*iw/zoom&#x27;,&#xA;                    y: &#x27;ih/2-ih*(1/2-33/100)*ih/zoom&#x27;,&#xA;                    s: &#x27;1080x1920&#x27;, // Output size&#xA;                    fps: &#x27;60&#x27;&#xA;                },&#xA;                inputs: [`${i &#x2B; 1}:v`],&#xA;                outputs: `zoomed${i &#x2B; 1}`&#xA;            },&#xA;            xfadeFilter: {&#xA;                filter: &#x27;xfade&#x27;,&#xA;                options: {&#xA;                    transition: &#x27;fade&#x27;, // Crossfade transition effect&#xA;                    duration: &#x27;0.5&#x27;, // Duration of crossfade in seconds&#xA;                    offset: `${imageDuration - 1}` // Offset to start the crossfade&#xA;                },&#xA;                inputs: [`zoomed${i &#x2B; 1}`, `zoomed${i}`],&#xA;                outputs: `crossfaded${i}`&#xA;            },&#xA;        };&#xA;    });&#xA;

    &#xA;

    This is my complete code :

    &#xA;

    async function createVideo() {&#xA;    // Escape file paths for Windows&#xA;    const videoPath = path.resolve(__dirname&#x2B; &#x27;/output.mp4&#x27;).replace(/\\/g, &#x27;\\\\&#x27;);&#xA;    const audioPath = path.resolve(__dirname&#x2B; &#x27;/output.mp3&#x27;).replace(/\\/g, &#x27;\\\\&#x27;);&#xA;    const backgroundMusicPath = path.resolve(__dirname&#x2B; &#x27;/background-music.mp3&#x27;).replace(/\\/g, &#x27;\\\\&#x27;);&#xA;&#xA;    const command = ffmpeg();&#xA;&#xA;    const imagesDir = path.join(__dirname, &#x27;images&#x27;);&#xA;    const images = fs.readdirSync(imagesDir)&#xA;        .filter(file => /.(jpg|jpeg|png)$/i.test(file)) // Filter image files&#xA;        .sort() // Sort filenames to ensure the correct order&#xA;        .map(file => path.join(imagesDir, file));&#xA;&#xA;        images.map((image) => command.input(image))&#xA;&#xA;    const imageCount = images.length;&#xA;    const audioDuration = await getAudioDurationInSeconds(audioPath);&#xA;    const imageDuration =  Math.round(audioDuration / imageCount)&#xA;&#xA;    const filters = Array.from({ length: imageCount - 1 }).map((_, i) => {&#xA;        const rndInt = Math.floor(Math.random() * 1000) &#x2B; 1&#xA;&#xA;        return {&#xA;            zoompanFilter1: {&#xA;                filter: &#x27;zoompan&#x27;,&#xA;                options: {&#xA;                    z: &#x27;min(zoom&#x2B;0.001,1.3)&#x27;, // Reset zoom to 1.0&#xA;                    d: `${imageDuration * 60}`, // Duration of the zoom effect&#xA;                    x: `iw/2-iw*(1/2-${rndInt}/100)*iw/zoom`, // Center x&#xA;                    y: `ih/2-ih*(1/2-${rndInt}/100)*ih/zoom`, // Center y&#xA;                    s: &#x27;1080x1920&#x27;, // Output size&#xA;                    fps: &#x27;60&#x27;&#xA;                },&#xA;                inputs: `[${i}:v]`,&#xA;                outputs: `zoomed${i}`&#xA;            },&#xA;            zoompanFilter2: {&#xA;                filter: &#x27;zoompan&#x27;,&#xA;                options: {&#xA;                    z: &#x27;min(zoom&#x2B;0.001,1.3)&#x27;, // Reset zoom to 1.0&#xA;                    d: `${imageDuration * 60}`, // Duration of the zoom effect&#xA;                    x: &#x27;iw/2-iw*(1/2-33/100)*iw/zoom&#x27;, // Center x&#xA;                    y: &#x27;ih/2-ih*(1/2-33/100)*ih/zoom&#x27;, // Center y&#xA;                    s: &#x27;1080x1920&#x27;, // Output size&#xA;                    fps: &#x27;60&#x27;&#xA;                },&#xA;                inputs: [`${i &#x2B; 1}:v`],&#xA;                outputs: `zoomed${i &#x2B; 1}`&#xA;            },&#xA;            xfadeFilter: {&#xA;                filter: &#x27;xfade&#x27;,&#xA;                options: {&#xA;                    transition: &#x27;fade&#x27;, // Crossfade transition effect&#xA;                    duration: &#x27;0.5&#x27;, // Duration of crossfade in seconds&#xA;                    offset: `${imageDuration - 1}` // Offset to start the crossfade&#xA;                },&#xA;                inputs: [`zoomed${i &#x2B; 1}`, `zoomed${i}`],&#xA;                outputs: `crossfaded${i}`&#xA;            },&#xA;        };&#xA;    });&#xA;&#xA;    command&#xA;    .input(audioPath)&#xA;    .input(backgroundMusicPath)&#xA;    .outputOptions([&#xA;        &#x27;-pix_fmt&#x27;, &#x27;yuv420p&#x27;,&#xA;        &#x27;-c:v&#x27;, &#x27;libx264&#x27;,&#xA;        &#x27;-c:a&#x27;, &#x27;aac&#x27;,&#xA;        &#x27;-y&#x27;,&#xA;        &#x27;-t&#x27;, `${audioDuration}`,&#xA;        &#x27;-r&#x27;, &#x27;60&#x27;,&#xA;        &#x27;-s&#x27;, &#x27;1080x1920&#x27;,&#xA;        &#x27;-preset&#x27;, &#x27;ultrafast&#x27;,&#xA;        &#x27;-map&#x27;, &#x27;[final_video]&#x27;,&#xA;        &#x27;-map&#x27;, &#x27;[mixed_audio]&#x27;,&#xA;    ])&#xA;    .complexFilter([&#xA;        // Apply zoompan filters and xfade transitions&#xA;        ...filters.flatMap(({ zoompanFilter1, zoompanFilter2, xfadeFilter }) => [&#xA;            zoompanFilter1,&#xA;            zoompanFilter2,&#xA;            xfadeFilter,&#xA;        ]),&#xA;        {&#xA;            filter: &#x27;concat&#x27;,&#xA;            options: {&#xA;                n: imageCount - 1, // Number of videos to concatenate&#xA;                v: 1, // Video streams&#xA;                a: 0 // No audio streams&#xA;            },&#xA;            inputs: filters.map((_, i) => `crossfaded${i}`),&#xA;            outputs: &#x27;video_sequence&#x27;&#xA;        },&#xA;        {&#xA;            filter: &#x27;curves&#x27;,&#xA;            options: &#x27;preset=increase_contrast&#x27;,&#xA;            inputs: &#x27;video_sequence&#x27;,&#xA;            outputs: &#x27;curves&#x27;&#xA;        },&#xA;        {&#xA;            filter: &#x27;subtitles&#x27;,&#xA;            options: `./subtitles.ass:fontsdir=./fonts/:force_style=&#x27;FontName=Montserrat Black Italic,FontSize=17,MarginL=10,MarginV=25,Alignment=10,Spacing=0.2,Outline=0.1,Shadow=1.5&#x27;`,&#xA;            inputs: &#x27;[curves]&#x27;,&#xA;            outputs: &#x27;final_video&#x27;&#xA;        },&#xA;        {&#xA;            filter: &#x27;volume&#x27;,&#xA;            options: 0.3,  // Adjust the volume to 25% of the original&#xA;            inputs: `${imageCount &#x2B; 1}:a`,&#xA;            outputs: &#x27;background_music_adjusted&#x27;&#xA;        },&#xA;        // Apply the amix filter to mix the two audio inputs&#xA;        {&#xA;            filter: &#x27;amix&#x27;,&#xA;            options: {&#xA;                inputs: 2,&#xA;                duration: &#x27;first&#x27;,&#xA;                dropout_transition: 0,&#xA;                weights: &#x27;1 0.25&#x27;,&#xA;                normalize: 0&#xA;            },&#xA;            inputs: [`${imageCount}:a`, &#x27;background_music_adjusted&#x27;],&#xA;            outputs: &#x27;mixed_audio&#x27;&#xA;        },&#xA;      ])&#xA;    .save(videoPath)&#xA;    .on(&#x27;progress&#x27;, function(progress) {&#xA;        console.log(&#x27;Processing: &#x27; &#x2B; progress.percent &#x2B; &#x27;% done&#x27;);&#xA;      })&#xA;    .on(&#x27;end&#x27;, function(stdout, stderr) {&#xA;        // emptyFolder(imagesDir)&#xA;        console.log(&#x27;Transcoding succeeded !&#x27;);&#xA;      }) &#xA;    .on(&#x27;error&#x27;, function(err) {&#xA;        console.error(&#x27;Une erreur s\&#x27;est produite :&#x27;, err.message);&#xA;    });&#xA;}&#xA;

    &#xA;

    My problem is I see the 1 image then the transition and i see the 2 image. After that I'm supposed to see the 3 image but I see the 2 image.

    &#xA;

    What am I doing wrong ?

    &#xA;

    I tried switching the inputs: [`zoomed${i &#x2B; 1}`, `zoomed${i}`] to inputs: [`zoomed${i}`, `zoomed${i&#x2B;1}`] but it just showed the next image and not a loop of consecutive images.

    &#xA;