Recherche avancée

Médias (91)

Autres articles (63)

  • Le profil des utilisateurs

    12 avril 2011, par

    Chaque 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 (...)

  • Configurer la prise en compte des langues

    15 novembre 2010, par

    Accéder à la configuration et ajouter des langues prises en compte
    Afin de configurer la prise en compte de nouvelles langues, il est nécessaire de se rendre dans la partie "Administrer" du site.
    De là, dans le menu de navigation, vous pouvez accéder à une partie "Gestion des langues" permettant d’activer la prise en compte de nouvelles langues.
    Chaque nouvelle langue ajoutée reste désactivable tant qu’aucun objet n’est créé dans cette langue. Dans ce cas, elle devient grisée dans la configuration et (...)

  • Les tâches Cron régulières de la ferme

    1er décembre 2010, par

    La 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 (4967)

  • How to create a command – Introducing the Piwik Platform

    2 octobre 2014, par Thomas Steur — Development

    This is the next post of our blog series where we introduce the capabilities of the Piwik platform (our previous post was How to publish your plugin or theme on the Piwik Marketplace). This time you’ll learn how to create a new command. For this tutorial you will need to have basic knowledge of PHP.

    What is a command ?

    A command can execute any task on the command line. Piwik provides currently about 50 commands via the Piwik Console. These commands let you start the archiver, change the number of available custom variables, enable the developer mode, clear caches, run tests and more. You could write your own command to sync users or websites with another system for instance.

    Getting started

    In this series of posts, we assume that you have already set up your development environment. If not, visit the Piwik Developer Zone where you’ll find the tutorial Setting up Piwik.

    To summarize the things you have to do to get setup :

    • Install Piwik (for instance via git).
    • Activate the developer mode : ./console development:enable --full.
    • Generate a plugin : ./console generate:plugin --name="MyCommandPlugin". There should now be a folder plugins/MyCommandPlugin.
    • And activate the created plugin under Settings => Plugins.

    Let’s start creating a command

    We start by using the Piwik Console to create a new command. As you can see there is even a command that lets you easily create a new command :

    ./console generate:command

    The command will ask you to enter the name of the plugin the created command should belong to. I will simply use the above chosen plugin name “MyCommandPlugin”. It will ask you for a command name as well. I will use “SyncUsers” in this example. There should now be a file plugins/MyCommandPlugin/Commands/Syncusers.php which contains already an example to get you started easily :

    1. class Syncusers extends ConsoleCommand
    2. {
    3.     protected function configure()
    4.     {
    5.         $this->setName('mycommandplugin:syncusers');
    6.         $this->setDescription('MyCommandPlugin');
    7.         $this->addOption('name', null, InputOption::VALUE_REQUIRED, 'Your name:');
    8.     }
    9.  
    10.     /**
    11.      * Execute command like: ./console mycommandplugin:syncusers --name="The Piwik Team"
    12.      */
    13.     protected function execute(InputInterface $input, OutputInterface $output)
    14.     {
    15.         $name    = $input->getOption('name');
    16.  
    17.         $message = sprintf('Syncusers: %s', $name);
    18.  
    19.         $output->writeln($message);
    20.     }
    21. }

    Télécharger

    Any command that is placed in the “Commands” folder of your plugin will be available on the command line automatically. Therefore, the newly created command can now be executed via ./console mycommandplugin:syncusers --name="The Piwik Team".

    The code template explained

    1. protected function configure()
    2. {
    3.     $this->setName('mycommandplugin:checkdatabase');
    4.     $this->setDescription('MyCommandPlugin');
    5.     $this->addOption('name', null, InputOption::VALUE_REQUIRED, 'Your name:');
    6. }

    Télécharger

    As the name says the method configure lets you configure your command. You can define the name and description of your command as well as all the options and arguments you expect when executing it.

    1. protected function execute(InputInterface $input, OutputInterface $output)
    2. {
    3.     $name    = $input->getOption('name');
    4.     $message = sprintf('Syncusers: %s', $name);
    5.     $output->writeln($message);
    6. }

    Télécharger

    The actual task is defined in the execute method. There you can access any option or argument that was defined on the command line via $input and write anything to the console via $output argument.

    In case anything went wrong during the execution you should throw an exception to make sure the user will get a useful error message. Throwing an exception when an error occurs will make sure the command does exit with a status code different than 0 which can sometimes be important.

    Advanced features

    The Piwik Console is based on the powerful Symfony Console component. For instance you can ask a user for any interactive input, you can use different output color schemes and much more. If you are interested in learning more all those features have a look at the Symfony console website.

    How to test a command

    After you have created a command you are surely wondering how to test it. Ideally, the actual command is quite short as it acts like a controller. It should only receive the input values, execute the task by calling a method of another class and output any useful information. This allows you to easily create a unit or integration test for the classes behind the command. We will cover this topic in one of our future blog posts. Just one hint : You can use another command ./console generate:test to create a test. If you want to know how to test a command have a look at the Testing Commands documentation.

    Publishing your Plugin on the Marketplace

    In case you want to share your commands with other Piwik users you can do this by pushing your plugin to a public GitHub repository and creating a tag. Easy as that. Read more about how to distribute a plugin and best practices when publishing a plugin.

    Isn’t it easy to create a command ? We never even created a file ! If you have any feedback regarding our APIs or our guides in the Developer Zone feel free to send it to us.

  • Enhanced Privacy Control : Matomo’s Guide for Consent Manager Platform Integrations

    13 février, par Alex Carmona — Development, Latest Releases

    In today’s digital landscape, protecting user privacy isn’t just about compliance—it’s about building trust and demonstrating respect for user choices. Even though you can use Matomo without requiring consent when properly configured in compliance with privacy regulations, we’re excited to introduce a new Consent Manager Platforms (CMP) category on our Integrations page to make it easier than ever to implement privacy-respecting analytics.

    What’s a consent manager platform ?

    Consent Management Platform (CMP) is a tool that helps websites collect, manage, and store user consent for data tracking and cookies in compliance with privacy regulations like GDPR and CCPA. A CMP allows users to choose which types of data they want to share, ensuring transparency and respecting their privacy preferences. By integrating a CMP with Matomo, organisations can make sure that analytics tracking occurs only after obtaining explicit user consent.

    detailed consent flow explianed for CMP

    Remember, you can configure Matomo to remain fully GDPR compliant, without requiring user consent.

    Why consent management matters

    With privacy regulations reshaping data collection practices daily, organisations need to ensure that analytics data is gathered only after users have explicitly given their consent. Integrating Matomo with a Consent Management Platform helps you :

    • Strengthen regulatory compliance
    • Enhance user trust through transparency
    • Clearly document consent choices
    • Simplify privacy management

    By making consent management seamless, you can maintain compliance while delivering a privacy-first experience to your users.

    Introducing our CMP integration options

    We’ve carefully curated integrations with leading Consent Management Platforms that work seamlessly with Matomo Analytics and Matomo Tag Manager. Our supported platforms include :

    All cmp platforms integration for Matomo

    Supported consent management platforms

    • Osano – Comprehensive consent management with global regulation support
    • Cookiebot – Advanced cookie consent and compliance automation
    • CookieYes – User-friendly consent management solution
    • Tarte au Citron – Open-source consent management tool
    • Klaro – Privacy-focused consent management system
    • OneTrust – Enterprise-grade privacy management platform
    • Complianz for WordPress – Specialised WordPress consent solution

    Each platform provides unique features and compliance options, allowing you to select the best fit for your privacy needs.

    Getting started with simplified implementation

    Ready to enhance your privacy compliance ? We’ve made the integration process straightforward, so you can set up a privacy-compliant analytics environment in just a few steps. Here’s how to begin :

    1. Explore our new CMP category on the Integrations page
    2. Select and implement the CMP that best suits your needs
    3. Check our implementation guides for step-by-step instructions
    4. Configure your consent management settings in Matomo
    5. Start collecting analytics data with proper consent management

    Moving Forward

    As privacy regulations evolve and user expectations around data protection grow, proper consent management is more important than ever. With Matomo’s new CMP integrations, you can ensure compliance while maintaining full control over your analytics data.

    Visit our Integrations page and our Implementation guides today to explore these privacy-enhancing solutions and take the next step in your privacy-first analytics journey.

  • Rendering YUV420P ffmpeg decoded images on QT with OpenGL, only see black screen

    17 février 2019, par Lucas Zanella

    I’ve found this QT OpenGL Widget which should render a 420PYUV image on screen. I’m feeding a ffmpeg decoded buffer into its paintGL() function but I see nothing. Neither noises or correct images, only a black screen. I’m trying to understand why.

    I want to exclude the possibilities of other things being wrong, but I need to be sure first that my code will produce anything. I std::couted some bytes from the ffmpeg just to see if they were arriving and they were. So I should see at least some noise.

    Can you see anything wrong with my code that wouldn’t make it able to render images on screen ?

    This is the widget that should output the image :

    #include "XVideoWidget.h"
    #include <qdebug>
    #include <qtimer>
    #include <iostream>
    //自动加双引号
    #define GET_STR(x) #x
    #define A_VER 3
    #define T_VER 4

    //顶点shader
    const char *vString = GET_STR(
       attribute vec4 vertexIn;
       attribute vec2 textureIn;
       varying vec2 textureOut;
       void main(void)
       {
           gl_Position = vertexIn;
           textureOut = textureIn;
       }
    );


    //片元shader
    const char *tString = GET_STR(
       varying vec2 textureOut;
       uniform sampler2D tex_y;
       uniform sampler2D tex_u;
       uniform sampler2D tex_v;
       void main(void)
       {
           vec3 yuv;
           vec3 rgb;
           yuv.x = texture2D(tex_y, textureOut).r;
           yuv.y = texture2D(tex_u, textureOut).r - 0.5;
           yuv.z = texture2D(tex_v, textureOut).r - 0.5;
           rgb = mat3(1.0, 1.0, 1.0,
               0.0, -0.39465, 2.03211,
               1.13983, -0.58060, 0.0) * yuv;
           gl_FragColor = vec4(rgb, 1.0);
       }

    );



    //准备yuv数据
    // ffmpeg -i v1080.mp4 -t 10 -s 240x128 -pix_fmt yuv420p  out240x128.yuv
    XVideoWidget::XVideoWidget(QWidget * parent)
    {
      // setWindowFlags (Qt::WindowFullscreenButtonHint);
     //  showFullScreen();

    }

    XVideoWidget::~XVideoWidget()
    {
    }

    //初始化opengl
    void XVideoWidget::initializeGL()
    {
       //qDebug() &lt;&lt; "initializeGL";
       std::cout &lt;&lt; "initializing gl" &lt;&lt; std::endl;
       //初始化opengl (QOpenGLFunctions继承)函数
       initializeOpenGLFunctions();

       this->m_F  = QOpenGLContext::currentContext()->functions();

       //program加载shader(顶点和片元)脚本
       //片元(像素)
       std::cout &lt;&lt; program.addShaderFromSourceCode(QOpenGLShader::Fragment, tString) &lt;&lt; std::endl;
       //顶点shader
       std::cout &lt;&lt; program.addShaderFromSourceCode(QOpenGLShader::Vertex, vString) &lt;&lt; std::endl;

       //设置顶点坐标的变量
       program.bindAttributeLocation("vertexIn",A_VER);

       //设置材质坐标
       program.bindAttributeLocation("textureIn",T_VER);

       //编译shader
       std::cout &lt;&lt; "program.link() = " &lt;&lt; program.link() &lt;&lt; std::endl;

       std::cout &lt;&lt; "program.bind() = " &lt;&lt; program.bind() &lt;&lt; std::endl;

       //传递顶点和材质坐标
       //顶点
       static const GLfloat ver[] = {
           -1.0f,-1.0f,
           1.0f,-1.0f,
           -1.0f, 1.0f,
           1.0f,1.0f
       };

       //材质
       static const GLfloat tex[] = {
           0.0f, 1.0f,
           1.0f, 1.0f,
           0.0f, 0.0f,
           1.0f, 0.0f
       };

       //顶点
       glVertexAttribPointer(A_VER, 2, GL_FLOAT, 0, 0, ver);
       glEnableVertexAttribArray(A_VER);

       //材质
       glVertexAttribPointer(T_VER, 2, GL_FLOAT, 0, 0, tex);
       glEnableVertexAttribArray(T_VER);

       //glUseProgram(&amp;program);
       //从shader获取材质
       unis[0] = program.uniformLocation("tex_y");
       unis[1] = program.uniformLocation("tex_u");
       unis[2] = program.uniformLocation("tex_v");

       //创建材质
       glGenTextures(3, texs);

       //Y
       glBindTexture(GL_TEXTURE_2D, texs[0]);
       //放大过滤,线性插值   GL_NEAREST(效率高,但马赛克严重)
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
       //创建材质显卡空间
       glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, 0);

       //U
       glBindTexture(GL_TEXTURE_2D, texs[1]);
       //放大过滤,线性插值
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
       //创建材质显卡空间
       glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width/2, height / 2, 0, GL_RED, GL_UNSIGNED_BYTE, 0);

       //V
       glBindTexture(GL_TEXTURE_2D, texs[2]);
       //放大过滤,线性插值
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
       //创建材质显卡空间
       glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width / 2, height / 2, 0, GL_RED, GL_UNSIGNED_BYTE, 0);

       ///分配材质内存空间
       datas[0] = new unsigned char[width*height];     //Y
       datas[1] = new unsigned char[width*height/4];   //U
       datas[2] = new unsigned char[width*height/4];   //V
    }

    //刷新显示
    void XVideoWidget::paintGL(unsigned char**data)
    //void QFFmpegGLWidget::updateData(unsigned char**data)
    {
       std::cout &lt;&lt; "painting!" &lt;&lt; std::endl;
       memcpy(datas[0], data[0], width*height);
       memcpy(datas[1], data[1], width*height/4);
       memcpy(datas[2], data[2], width*height/4);

       glActiveTexture(GL_TEXTURE0);
       glBindTexture(GL_TEXTURE_2D, texs[0]); //0层绑定到Y材质
       //修改材质内容(复制内存内容)
       glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RED, GL_UNSIGNED_BYTE, datas[0]);
       //与shader uni遍历关联
       glUniform1i(unis[0], 0);


       glActiveTexture(GL_TEXTURE0+1);
       glBindTexture(GL_TEXTURE_2D, texs[1]); //1层绑定到U材质
                                              //修改材质内容(复制内存内容)
       glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width/2, height / 2, GL_RED, GL_UNSIGNED_BYTE, datas[1]);
       //与shader uni遍历关联
       glUniform1i(unis[1],1);


       glActiveTexture(GL_TEXTURE0+2);
       glBindTexture(GL_TEXTURE_2D, texs[2]); //2层绑定到V材质
                                              //修改材质内容(复制内存内容)
       glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width / 2, height / 2, GL_RED, GL_UNSIGNED_BYTE, datas[2]);
       //与shader uni遍历关联
       glUniform1i(unis[2], 2);

       glDrawArrays(GL_TRIANGLE_STRIP,0,4);
       qDebug() &lt;&lt; "paintGL";
    }


    // 窗口尺寸变化
    void XVideoWidget::resizeGL(int width, int height)
    {
       m_F->glViewport(0, 0, width, height);

       qDebug() &lt;&lt; "resizeGL "&lt;code></iostream></qtimer></qdebug>

    Here’s a bit of code from my MainWindow :

    MainWindow::MainWindow(QWidget *parent):
       QMainWindow(parent)
       {
           FfmpegDecoder* ffmpegDecoder = new FfmpegDecoder();
           if(!ffmpegDecoder->Init()) {
               std::cout &lt;&lt; "problem with ffmpeg decoder init"  &lt;&lt; std::endl;
           } else {
               std::cout &lt;&lt; "fmmpeg decoder initiated"  &lt;&lt; std::endl;
           }
           XVideoWidget * xVideoWidget = new XVideoWidget(parent);
           ffmpegDecoder->setOpenGLWidget(xVideoWidget);

           mediaStream = new MediaStream(uri, ffmpegDecoder, videoConsumer);//= new MediaStream(uri, ffmpegDecoder, videoConsumer);
           //...
       }
       void MainWindow::run()
       {
           mediaStream->receiveFrame();
       }

    My main.cpp makes sure my window run() method runs in the background.

       MainWindow w;
       w.setFixedSize(1280,720);
       w.show();
       boost::thread mediaThread(&amp;MainWindow::run, &amp;w);
       std::cout &lt;&lt; "mediaThread running"  &lt;&lt; std::endl;

    If someone wants to view the entire code, please feel free to visit the commit I just did : https://github.com/lucaszanella/orwell/tree/bbd74e42bd42df685bacc5d51cacbee3a178689f