Recherche avancée

Médias (0)

Mot : - Tags -/content

Aucun média correspondant à vos critères n’est disponible sur le site.

Autres articles (52)

  • Personnaliser en ajoutant son logo, sa bannière ou son image de fond

    5 septembre 2013, par

    Certains 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 ;

  • Ecrire une actualité

    21 juin 2013, par

    Présentez les changements dans votre MédiaSPIP ou les actualités de vos projets sur votre MédiaSPIP grâce à la rubrique actualités.
    Dans le thème par défaut spipeo de MédiaSPIP, les actualités sont affichées en bas de la page principale sous les éditoriaux.
    Vous pouvez personnaliser le formulaire de création d’une actualité.
    Formulaire de création d’une actualité Dans le cas d’un document de type actualité, les champs proposés par défaut sont : Date de publication ( personnaliser la date de publication ) (...)

  • Publier sur MédiaSpip

    13 juin 2013

    Puis-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

Sur d’autres sites (3876)

  • Matomo analytics for wordpress

    15 octobre 2019, par Matomo Core Team — Community

    Self-hosting web analytics got a whole lot easier ! Introducing Matomo for WordPress

    Be the first to try it out ! Your feedback is much needed and appreciated

    Get a fully functioning Matomo (which is comparable to Google Analytics) in seconds ! How ? With the new Matomo Analytics for WordPress plugin. 

    Web analytics in WordPress has never been easier to get, or more powerful. Matomo Analytics for WordPress is the one-stop problem solver. It’ll save you time, money and give you the insights to help your website or business succeed. 

    Best of all, we get to further the goal of decentralising the internet. Our hope is for Matomo Analytics for WordPress to spread far and wide. We’re so excited that more and more people can now get their hands on this powerful, free, open-source analytics platform, in a few clicks !

    Download now and check it out !

    What do you get ?

    • No more signing up to third party analytics service (like Google)
    • No more sending away your valuable data to a third party service (like Google)
    • Easy setup – install with a few clicks, no tracking code installation or developer knowledge needed
    • 100% accurate data – no data sampling and no data limits 
    • Full data ownership – all data is stored on your servers and no one else can see your data
    • Privacy protection / GDPR compliance
    • Ecommerce tracking out-of-the-box (Woocommerce, Easy Digital Downloads, and MemberPress) and we’re keen to add many more over time
    • Powerful features – segmenting, comparing reports, different visualisations, real-time reports, visit logs and visitor profiles, Matomo Tag Manager, dashboards, data export, APIs, and many more
    • Compared to other WordPress solutions we don’t charge you extra for basic features that should work out-of-the-box
    • Just like Matomo On-Premise, Matomo Analytics for WordPress is free

    We need your feedback !

    We all know and love the versatility of WordPress – with over 55,000 plugins and all the different ways of hosting it. However, with this great versatility comes the potential for things to be missed, so we’re keen to hear your feedback.

    Thank you ! We really appreciate your help on this ❤️

    How do you get Matomo Analytics for WordPress ?

    You can then upload it in your WordPress by going to “Plugins => Add New”. During the upload, if you get an error like “Are you sure you want to do this ?”, we recommend you upload the extracted zip file on to your server and into your ‘wp-content/plugins’ folder manually using ftp or ssh. Make sure the plugin name is ‘matomo’.

    All you need is at least WordPress 4.8 and PHP 7.0 or later. MySQL 5.1+ is recommended. 

    The source code is available at : https://github.com/matomo-org/wp-matomo/

    In perfect harmony : Matomo and WordPress

    Matomo Analytics for WordPress

    The idea for this started two years ago when we realised the similarities between the Matomo and WordPress project. 

    Not only from a technological point of view – where both are based on PHP and MySQL and can be extended using plugins – but also from a philosophical, license and values point of view. We both believe in privacy, security, data ownership, openness, transparency, having things working out-of-the-box, simplicity etc. 

    WordPress is currently used on approximately 30% of all websites. Many of them use the self-hosted open-source WordPress version. Giving everyone in this market the opportunity to easily get a powerful web analytics platform for free, means a lot to us. We believe WordPress users get a real choice besides the standard solution of Google Analytics, and it furthers our effort and goal of decentralising the internet. 

    We’re hoping more people will be empowered to protect user privacy, have access to a great free and open-source tool, and keep control of data in their own hands.

    We hope you feel the same. Help us spread the word to your friends and get them in on this awesome new project !

    Share on facebook
    Share on twitter
    Share on linkedin

    FAQs

    Isn’t there already a WP-Matomo plugin for WordPress available ?

    Yes, the existing WP-Matomo (WP-Piwik) plugin is an awesome plugin to connect your existing Matomo On-Premise or Matomo Cloud account with WordPress. The difference is that this new plugin installs Matomo Analytics fully in your WordPress. So you get the convenience of having a powerful analytics platform within your WordPress.

    We highly recommend you install this new plugin if you use WordPress and are not running Matomo yet. 

    If you are already using Matomo on our Cloud or On-Premise, we’d still highly recommend you use WP-Matomo (WP-Piwik). So that you get an easier way of inserting the tracking code into your WordPress site and get insights faster.

    I have a high traffic website, will it be an issue ?

    If you have a lot of traffic, we’d advise you to install Matomo On-Premise separately. There’s no specific traffic threshold we can give you on when it’s better to use Matomo On-Premise. It really depends on your server. 

    We reckon if you have more than 500,000 page views a month, you may want to think about using Matomo On-Premise with WP-Matomo instead, but this is just an estimate. In general, if the load on your server is already quite high, then it might be better to install Matomo on a separate server. See also recommended server sizing for running Matomo.

    How do I report a bug or request a new feature in Matomo for WordPress ?

    Please create an issue, on our repository whenever you find a bug or if you have any suggestion or ideas of improvement. We want to build an outstanding analytics experience for WordPress !

    Have another question you’re dying to ask ? The Matomo for WordPress FAQ page might have the answer you need. 

    Matomo Analytics for WordPress newsletter

    Get ahead of the crowd – signup to our exclusive Matomo for WordPress newsletter to get the latest updates on this exciting new project.

    &lt;script type=&quot;text/javascript&quot;&gt;<br />
    (function(global) {<br />
     function serialize(form){if(!form||form.nodeName!==&quot;FORM&quot;){return }var i,j,q=[];for(i=form.elements.length-1;i&gt;=0;i=i-1){if(form.elements[i].name===&quot;&quot;){continue}switch(form.elements[i].nodeName){case&quot;INPUT&quot;:switch(form.elements[i].type){case&quot;text&quot;:case&quot;hidden&quot;:case&quot;password&quot;:case&quot;button&quot;:case&quot;reset&quot;:case&quot;submit&quot;:q.push(form.elements[i].name+&quot;=&quot;+encodeURIComponent(form.elements[i].value));break;case&quot;checkbox&quot;:case&quot;radio&quot;:if(form.elements[i].checked){q.push(form.elements[i].name+&quot;=&quot;+encodeURIComponent(form.elements[i].value))}break;case&quot;file&quot;:break}break;case&quot;TEXTAREA&quot;:q.push(form.elements[i].name+&quot;=&quot;+encodeURIComponent(form.elements[i].value));break;case&quot;SELECT&quot;:switch(form.elements[i].type){case&quot;select-one&quot;:q.push(form.elements[i].name+&quot;=&quot;+encodeURIComponent(form.elements[i].value));break;case&quot;select-multiple&quot;:for(j=form.elements[i].options.length-1;j&gt;=0;j=j-1){if(form.elements[i].options[j].selected){q.push(form.elements[i].name+&quot;=&quot;+encodeURIComponent(form.elements[i].options[j].value))}}break}break;case&quot;BUTTON&quot;:switch(form.elements[i].type){case&quot;reset&quot;:case&quot;submit&quot;:case&quot;button&quot;:q.push(form.elements[i].name+&quot;=&quot;+encodeURIComponent(form.elements[i].value));break}break}}return q.join(&quot;&amp;&quot;)};<br />
    <br />
    <br />
     function extend(destination, source) {<br />
       for (var prop in source) {<br />
         destination[prop] = source[prop];<br />
       }<br />
     }<br />
    <br />
     if (!Mimi) var Mimi = {};<br />
     if (!Mimi.Signups) Mimi.Signups = {};<br />
    <br />
     Mimi.Signups.EmbedValidation = function() {<br />
       this.initialize();<br />
    <br />
       var _this = this;<br />
       if (document.addEventListener) {<br />
         this.form.addEventListener('submit', function(e){<br />
           _this.onFormSubmit(e);<br />
         });<br />
       } else {<br />
         this.form.attachEvent('onsubmit', function(e){<br />
           _this.onFormSubmit(e);<br />
         });<br />
       }<br />
     };<br />
    <br />
     extend(Mimi.Signups.EmbedValidation.prototype, {<br />
       initialize: function() {<br />
         this.form         = document.getElementById('ema_signup_form');<br />
         this.submit       = document.getElementById('webform_submit_button');<br />
         this.callbackName = 'jsonp_callback_' + Math.round(100000 * Math.random());<br />
         this.validEmail   = /.+@.+\..+/<br />
       },<br />
    <br />
       onFormSubmit: function(e) {<br />
         e.preventDefault();<br />
    <br />
         this.validate();<br />
         if (this.isValid) {<br />
           this.submitForm();<br />
         } else {<br />
           this.revalidateOnChange();<br />
         }<br />
       },<br />
    <br />
       validate: function() {<br />
         this.isValid = true;<br />
         this.emailValidation();<br />
         this.fieldAndListValidation();<br />
         this.updateFormAfterValidation();<br />
       },<br />
    <br />
       emailValidation: function() {<br />
         var email = document.getElementById('signup_email');<br />
    <br />
         if (this.validEmail.test(email.value)) {<br />
           this.removeTextFieldError(email);<br />
         } else {<br />
           this.textFieldError(email);<br />
           this.isValid = false;<br />
         }<br />
       },<br />
    <br />
       fieldAndListValidation: function() {<br />
         var fields = this.form.querySelectorAll('.mimi_field.required');<br />
    <br />
         for (var i = 0; i &lt; fields.length; ++i) {<br />
           var field = fields[i],<br />
               type  = this.fieldType(field);<br />
           if (type === 'checkboxes' || type === 'radio_buttons' || type === 'age_check') {<br />
             this.checkboxAndRadioValidation(field);<br />
           } else {<br />
             this.textAndDropdownValidation(field, type);<br />
           }<br />
         }<br />
       },<br />
    <br />
       fieldType: function(field) {<br />
         var type = field.querySelectorAll('.field_type');<br />
    <br />
         if (type.length) {<br />
           return type[0].getAttribute('data-field-type');<br />
         } else if (field.className.indexOf('checkgroup') &gt;= 0) {<br />
           return 'checkboxes';<br />
         } else {<br />
           return 'text_field';<br />
         }<br />
       },<br />
    <br />
       checkboxAndRadioValidation: function(field) {<br />
         var inputs   = field.getElementsByTagName('input'),<br />
             selected = false;<br />
    <br />
         for (var i = 0; i &lt; inputs.length; ++i) {<br />
           var input = inputs[i];<br />
           if((input.type === 'checkbox' || input.type === 'radio') &amp;&amp; input.checked) {<br />
             selected = true;<br />
           }<br />
         }<br />
    <br />
         if (selected) {<br />
           field.className = field.className.replace(/ invalid/g, '');<br />
         } else {<br />
           if (field.className.indexOf('invalid') === -1) {<br />
             field.className += ' invalid';<br />
           }<br />
    <br />
           this.isValid = false;<br />
         }<br />
       },<br />
    <br />
       textAndDropdownValidation: function(field, type) {<br />
         var inputs = field.getElementsByTagName('input');<br />
    <br />
         for (var i = 0; i &lt; inputs.length; ++i) {<br />
           var input = inputs[i];<br />
           if (input.name.indexOf('signup') &gt;= 0) {<br />
             if (type === 'text_field') {<br />
               this.textValidation(input);<br />
             } else {<br />
               this.dropdownValidation(field, input);<br />
             }<br />
           }<br />
         }<br />
         this.htmlEmbedDropdownValidation(field);<br />
       },<br />
    <br />
       textValidation: function(input) {<br />
         if (input.id === 'signup_email') return;<br />
    <br />
         if (input.value) {<br />
           this.removeTextFieldError(input);<br />
         } else {<br />
           this.textFieldError(input);<br />
           this.isValid = false;<br />
         }<br />
       },<br />
    <br />
       dropdownValidation: function(field, input) {<br />
         if (input.value) {<br />
           field.className = field.className.replace(/ invalid/g, '');<br />
         } else {<br />
           if (field.className.indexOf('invalid') === -1) field.className += ' invalid';<br />
           this.onSelectCallback(input);<br />
           this.isValid = false;<br />
         }<br />
       },<br />
    <br />
       htmlEmbedDropdownValidation: function(field) {<br />
         var dropdowns = field.querySelectorAll('.mimi_html_dropdown');<br />
         var _this = this;<br />
    <br />
         for (var i = 0; i &lt; dropdowns.length; ++i) {<br />
           var dropdown = dropdowns[i];<br />
    <br />
           if (dropdown.value) {<br />
             field.className = field.className.replace(/ invalid/g, '');<br />
           } else {<br />
             if (field.className.indexOf('invalid') === -1) field.className += ' invalid';<br />
             this.isValid = false;<br />
             dropdown.onchange = (function(){ _this.validate(); });<br />
           }<br />
         }<br />
       },<br />
    <br />
       textFieldError: function(input) {<br />
         input.className   = 'required invalid';<br />
         input.placeholder = input.getAttribute('data-required-field');<br />
       },<br />
    <br />
       removeTextFieldError: function(input) {<br />
         input.className   = 'required';<br />
         input.placeholder = '';<br />
       },<br />
    <br />
       onSelectCallback: function(input) {<br />
         if (typeof Widget === 'undefined' || !Widget.BasicDropdown) return;<br />
    <br />
         var dropdownEl = input.parentNode,<br />
             instances  = Widget.BasicDropdown.instances,<br />
             _this = this;<br />
    <br />
         for (var i = 0; i &lt; instances.length; ++i) {<br />
           var instance = instances[i];<br />
           if (instance.wrapperEl === dropdownEl) {<br />
             instance.onSelect = function(){ _this.validate() };<br />
           }<br />
         }<br />
       },<br />
    <br />
       updateFormAfterValidation: function() {<br />
         this.form.className   = this.setFormClassName();<br />
         this.submit.value     = this.submitButtonText();<br />
         this.submit.disabled  = !this.isValid;<br />
         this.submit.className = this.isValid ? 'submit' : 'disabled';<br />
       },<br />
    <br />
       setFormClassName: function() {<br />
         var name = this.form.className;<br />
    <br />
         if (this.isValid) {<br />
           return name.replace(/\s?mimi_invalid/, '');<br />
         } else {<br />
           if (name.indexOf('mimi_invalid') === -1) {<br />
             return name += ' mimi_invalid';<br />
           } else {<br />
             return name;<br />
           }<br />
         }<br />
       },<br />
    <br />
       submitButtonText: function() {<br />
         var invalidFields = document.querySelectorAll('.invalid'),<br />
             text;<br />
    <br />
         if (this.isValid || !invalidFields) {<br />
           text = this.submit.getAttribute('data-default-text');<br />
         } else {<br />
           if (invalidFields.length || invalidFields[0].className.indexOf('checkgroup') === -1) {<br />
             text = this.submit.getAttribute('data-invalid-text');<br />
           } else {<br />
             text = this.submit.getAttribute('data-choose-list');<br />
           }<br />
         }<br />
         return text;<br />
       },<br />
    <br />
       submitForm: function() {<br />
         this.formSubmitting();<br />
    <br />
         var _this = this;<br />
         window[this.callbackName] = function(response) {<br />
           delete window[this.callbackName];<br />
           document.body.removeChild(script);<br />
           _this.onSubmitCallback(response);<br />
         };<br />
    <br />
         var script = document.createElement('script');<br />
         script.src = this.formUrl('json');<br />
         document.body.appendChild(script);<br />
       },<br />
    <br />
       formUrl: function(format) {<br />
         var action  = this.form.action;<br />
         if (format === 'json') action += '.json';<br />
         return action + '?callback=' + this.callbackName + '&amp;' + serialize(this.form);<br />
       },<br />
    <br />
       formSubmitting: function() {<br />
         this.form.className  += ' mimi_submitting';<br />
         this.submit.value     = this.submit.getAttribute('data-submitting-text');<br />
         this.submit.disabled  = true;<br />
         this.submit.className = 'disabled';<br />
       },<br />
    <br />
       onSubmitCallback: function(response) {<br />
         if (response.success) {<br />
           this.onSubmitSuccess(response.result);<br />
         } else {<br />
           top.location.href = this.formUrl('html');<br />
         }<br />
       },<br />
    <br />
       onSubmitSuccess: function(result) {<br />
         if (result.has_redirect) {<br />
           top.location.href = result.redirect;<br />
         } else if(result.single_opt_in || !result.confirmation_html) {<br />
           this.disableForm();<br />
           this.updateSubmitButtonText(this.submit.getAttribute('data-thanks'));<br />
         } else {<br />
           this.showConfirmationText(result.confirmation_html);<br />
         }<br />
       },<br />
    <br />
       showConfirmationText: function(html) {<br />
         var fields = this.form.querySelectorAll('.mimi_field');<br />
    <br />
         for (var i = 0; i &lt; fields.length; ++i) {<br />
           fields[i].style['display'] = 'none';<br />
         }<br />
    <br />
         (this.form.querySelectorAll('fieldset')[0] || this.form).innerHTML = html;<br />
       },<br />
    <br />
       disableForm: function() {<br />
         var elements = this.form.elements;<br />
         for (var i = 0; i &lt; elements.length; ++i) {<br />
           elements[i].disabled = true;<br />
         }<br />
       },<br />
    <br />
       updateSubmitButtonText: function(text) {<br />
         this.submit.value = text;<br />
       },<br />
    <br />
       revalidateOnChange: function() {<br />
         var fields = this.form.querySelectorAll(&quot;.mimi_field.required&quot;),<br />
             _this = this;<br />
    <br />
         var onTextFieldChange = function() {<br />
           if (this.getAttribute('name') === 'signup[email]') {<br />
             if (_this.validEmail.test(this.value)) _this.validate();<br />
           } else {<br />
             if (this.value.length === 1) _this.validate();<br />
           }<br />
         }<br />
    <br />
         for (var i = 0; i &lt; fields.length; ++i) {<br />
           var inputs = fields[i].getElementsByTagName('input');<br />
           for (var j = 0; j &lt; inputs.length; ++j) {<br />
             if (this.fieldType(fields[i]) === 'text_field') {<br />
               inputs[j].onkeyup = onTextFieldChange;<br />
               inputs[j].onchange = onTextFieldChange; <br />
             } else {<br />
               inputs[j].onchange = function(){ _this.validate() };<br />
             }<br />
           }<br />
         }<br />
       }<br />
     });<br />
    <br />
     if (document.addEventListener) {<br />
       document.addEventListener(&quot;DOMContentLoaded&quot;, function() {<br />
         new Mimi.Signups.EmbedValidation();<br />
       });<br />
     }<br />
     else {<br />
       window.attachEvent('onload', function() {<br />
         new Mimi.Signups.EmbedValidation();<br />
       });<br />
     }<br />
    })(this);<br />
    &lt;/script&gt;
  • ffmpeg record video plays too fast

    29 avril 2023, par Kris Xia

    I'm a college student and I am studying FFmpeg now.

    &#xA;&#xA;

    I have wrote a software that can record desktops and audio('virtual-audio-capturer') with FFmpeg.And I am now writing Audio and Video Synchronization.&#xA;I met some problems that video recording plays too fast.

    &#xA;&#xA;

    When I look for audio and video synchronization help on the Internet,I find a formula for calculating PTS :

    &#xA;&#xA;

    pts = n * ((1 / timbase)/ fps)

    &#xA;&#xA;

    When I use this formula,I find a phenomenon.

    &#xA;&#xA;

    1.The higher frame rate is,the faster the video playback speed.

    &#xA;&#xA;

    2.The slower the frame rate, the faster the video playback.

    &#xA;&#xA;

    Also I find while the framerate is 10,the video playback speed will be right.

    &#xA;&#xA;

    Why has this situation happened ?

    &#xA;&#xA;

    I have thought this question for three days. I really hope someone can help me solve this problem.

    &#xA;&#xA;

    I really appreciate the help.

    &#xA;&#xA;

    #include "stdafx.h"&#xA;&#xA;#ifdef  __cplusplus&#xA;extern "C"&#xA;{&#xA;#endif&#xA;#include "libavcodec/avcodec.h"&#xA;#include "libavformat/avformat.h"&#xA;#include "libswscale/swscale.h"&#xA;#include "libavdevice/avdevice.h"&#xA;#include "libavutil/audio_fifo.h"&#xA;&#xA;#include "libavfilter/buffersink.h"&#xA;#include "libavfilter/buffersrc.h"&#xA;#include "libavutil/imgutils.h"&#xA;#include "libavutil/mathematics.h"&#xA;#include "libavutil/samplefmt.h"&#xA;#include "libavutil/time.h"&#xA;#include "libavutil/opt.h"&#xA;#include "libavutil/pixdesc.h"&#xA;#include "libavutil/file.h"&#xA;#include "libavutil/mem.h"&#xA;#include "libavutil/frame.h"&#xA;#include "libavfilter/avfilter.h"&#xA;#include "libswresample/swresample.h"&#xA;&#xA;#pragma comment(lib, "avcodec.lib")&#xA;#pragma comment(lib, "avformat.lib")&#xA;#pragma comment(lib, "avutil.lib")&#xA;#pragma comment(lib, "avdevice.lib")&#xA;#pragma comment(lib, "avfilter.lib")&#xA;&#xA;#pragma comment(lib, "avfilter.lib")&#xA;#pragma comment(lib, "postproc.lib")&#xA;#pragma comment(lib, "swresample.lib")&#xA;#pragma comment(lib, "swscale.lib")&#xA;#ifdef __cplusplus&#xA;};&#xA;#endif&#xA;&#xA;AVFormatContext *pFormatCtx_Video = NULL, *pFormatCtx_Audio = NULL, *pFormatCtx_Out = NULL;&#xA;&#xA;AVCodecContext *outVideoCodecCtx = NULL;&#xA;AVCodecContext *outAudioCodecCtx = NULL;&#xA;&#xA;AVStream *pVideoStream = NULL, *pAudioStream = NULL;&#xA;&#xA;AVCodec *outAVCodec;&#xA;AVCodec *outAudioCodec;&#xA;&#xA;AVCodecContext  *pCodecCtx_Video;&#xA;AVCodec         *pCodec_Video;&#xA;AVFifoBuffer    *fifo_video = NULL;&#xA;AVAudioFifo     *fifo_audio = NULL;&#xA;int VideoIndex, AudioIndex;&#xA;int codec_id;&#xA;&#xA;CRITICAL_SECTION AudioSection, VideoSection;&#xA;&#xA;&#xA;&#xA;SwsContext *img_convert_ctx;&#xA;int frame_size = 0;&#xA;&#xA;uint8_t *picture_buf = NULL, *frame_buf = NULL;&#xA;&#xA;bool bCap = true;&#xA;&#xA;DWORD WINAPI ScreenCapThreadProc( LPVOID lpParam );&#xA;DWORD WINAPI AudioCapThreadProc( LPVOID lpParam );&#xA;&#xA;int OpenVideoCapture()&#xA;{&#xA;    AVInputFormat *ifmt=av_find_input_format("gdigrab");&#xA;    AVDictionary *options = NULL;&#xA;    av_dict_set(&amp;options, "framerate", "60", NULL);&#xA;    if(avformat_open_input(&amp;pFormatCtx_Video, "desktop", ifmt, &amp;options)!=0)&#xA;    {&#xA;        printf("Couldn&#x27;t open input stream.(无法打开视频输入流)\n");&#xA;        return -1;&#xA;    }&#xA;    if(avformat_find_stream_info(pFormatCtx_Video,NULL)&lt;0)&#xA;    {&#xA;        printf("Couldn&#x27;t find stream information.(无法获取视频流信息)\n");&#xA;        return -1;&#xA;    }&#xA;    if (pFormatCtx_Video->streams[0]->codec->codec_type != AVMEDIA_TYPE_VIDEO)&#xA;    {&#xA;        printf("Couldn&#x27;t find video stream information.(无法获取视频流信息)\n");&#xA;        return -1;&#xA;    }&#xA;    pCodecCtx_Video = pFormatCtx_Video->streams[0]->codec;&#xA;    pCodec_Video = avcodec_find_decoder(pCodecCtx_Video->codec_id);&#xA;    if(pCodec_Video == NULL)&#xA;    {&#xA;        printf("Codec not found.(没有找到解码器)\n");&#xA;        return -1;&#xA;    }&#xA;    if(avcodec_open2(pCodecCtx_Video, pCodec_Video, NULL) &lt; 0)&#xA;    {&#xA;        printf("Could not open codec.(无法打开解码器)\n");&#xA;        return -1;&#xA;    }&#xA;&#xA;    av_dump_format(pFormatCtx_Video, 0, NULL, 0);&#xA;&#xA;    img_convert_ctx = sws_getContext(pCodecCtx_Video->width, pCodecCtx_Video->height, pCodecCtx_Video->pix_fmt, &#xA;        pCodecCtx_Video->width, pCodecCtx_Video->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL); &#xA;&#xA;    frame_size = avpicture_get_size(pCodecCtx_Video->pix_fmt, pCodecCtx_Video->width, pCodecCtx_Video->height);&#xA;    fifo_video = av_fifo_alloc(30 * avpicture_get_size(AV_PIX_FMT_YUV420P, pCodecCtx_Video->width, pCodecCtx_Video->height));&#xA;&#xA;    return 0;&#xA;}&#xA;&#xA;static char *dup_wchar_to_utf8(wchar_t *w)&#xA;{&#xA;    char *s = NULL;&#xA;    int l = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0);&#xA;    s = (char *) av_malloc(l);&#xA;    if (s)&#xA;        WideCharToMultiByte(CP_UTF8, 0, w, -1, s, l, 0, 0);&#xA;    return s;&#xA;}&#xA;&#xA;int OpenAudioCapture()&#xA;{&#xA;    AVInputFormat *pAudioInputFmt = av_find_input_format("dshow");&#xA;    char * psDevName = dup_wchar_to_utf8(L"audio=virtual-audio-capturer");&#xA;&#xA;    if (avformat_open_input(&amp;pFormatCtx_Audio, psDevName, pAudioInputFmt,NULL) &lt; 0)&#xA;    {&#xA;        printf("Couldn&#x27;t open input stream.(无法打开音频输入流)\n");&#xA;        return -1;&#xA;    }&#xA;&#xA;    if(avformat_find_stream_info(pFormatCtx_Audio,NULL)&lt;0)  &#xA;        return -1; &#xA;&#xA;    if(pFormatCtx_Audio->streams[0]->codec->codec_type != AVMEDIA_TYPE_AUDIO)&#xA;    {&#xA;        printf("Couldn&#x27;t find video stream information.(无法获取音频流信息)\n");&#xA;        return -1;&#xA;    }&#xA;&#xA;    AVCodec *tmpCodec = avcodec_find_decoder(pFormatCtx_Audio->streams[0]->codec->codec_id);&#xA;    if(0 > avcodec_open2(pFormatCtx_Audio->streams[0]->codec, tmpCodec, NULL))&#xA;    {&#xA;        printf("can not find or open audio decoder!\n");&#xA;    }&#xA;&#xA;    av_dump_format(pFormatCtx_Audio, 0, NULL, 0);&#xA;&#xA;    return 0;&#xA;}&#xA;&#xA;int OpenOutPut()&#xA;{&#xA;    AVStream *pVideoStream = NULL, *pAudioStream = NULL;&#xA;    const char *outFileName = "test.mp4";&#xA;    avformat_alloc_output_context2(&amp;pFormatCtx_Out, NULL, NULL, outFileName);&#xA;&#xA;    if (pFormatCtx_Video->streams[0]->codec->codec_type == AVMEDIA_TYPE_VIDEO)&#xA;    {&#xA;        VideoIndex = 0;&#xA;        pVideoStream = avformat_new_stream(pFormatCtx_Out, NULL);&#xA;        if (!pVideoStream)&#xA;        {&#xA;            printf("can not new stream for output!\n");&#xA;            return -1;&#xA;        }&#xA;&#xA;        outVideoCodecCtx = avcodec_alloc_context3(outAVCodec);&#xA;        if ( !outVideoCodecCtx )&#xA;        {&#xA;            printf("Error : avcodec_alloc_context3()\n");&#xA;            return -1;&#xA;        }&#xA;&#xA;        //set codec context param&#xA;        outVideoCodecCtx = pVideoStream->codec;&#xA;        outVideoCodecCtx->codec_id = AV_CODEC_ID_MPEG4;&#xA;        outVideoCodecCtx->width = pFormatCtx_Video->streams[0]->codec->width;&#xA;        outVideoCodecCtx->height = pFormatCtx_Video->streams[0]->codec->height;&#xA;        outVideoCodecCtx->time_base = pFormatCtx_Video->streams[0]->codec->time_base;&#xA;        outVideoCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;&#xA;        outVideoCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;&#xA;&#xA;        if (codec_id == AV_CODEC_ID_H264)&#xA;        {&#xA;            av_opt_set(outVideoCodecCtx->priv_data, "preset", "slow", 0);&#xA;        }&#xA;&#xA;        outAVCodec = avcodec_find_encoder(AV_CODEC_ID_MPEG4);&#xA;        if( !outAVCodec )&#xA;        {&#xA;            printf("\n\nError : avcodec_find_encoder()");&#xA;            return -1;&#xA;        }&#xA;        if (pFormatCtx_Out->oformat->flags &amp; AVFMT_GLOBALHEADER)&#xA;            outVideoCodecCtx->flags |=CODEC_FLAG_GLOBAL_HEADER;&#xA;&#xA;        if ((avcodec_open2(outVideoCodecCtx,outAVCodec, NULL)) &lt; 0)&#xA;        {&#xA;            printf("can not open the encoder\n");&#xA;            return -1;&#xA;        }&#xA;    }&#xA;&#xA;    if(pFormatCtx_Audio->streams[0]->codec->codec_type == AVMEDIA_TYPE_AUDIO)&#xA;    {&#xA;        AVCodecContext *pOutputCodecCtx;&#xA;        AudioIndex = 1;&#xA;        pAudioStream = avformat_new_stream(pFormatCtx_Out, NULL);&#xA;&#xA;        pAudioStream->codec->codec = avcodec_find_encoder(pFormatCtx_Out->oformat->audio_codec);&#xA;&#xA;        pOutputCodecCtx = pAudioStream->codec;&#xA;&#xA;        pOutputCodecCtx->sample_rate = pFormatCtx_Audio->streams[0]->codec->sample_rate;&#xA;        pOutputCodecCtx->channel_layout = pFormatCtx_Out->streams[0]->codec->channel_layout;&#xA;        pOutputCodecCtx->channels = av_get_channel_layout_nb_channels(pAudioStream->codec->channel_layout);&#xA;        if(pOutputCodecCtx->channel_layout == 0)&#xA;        {&#xA;            pOutputCodecCtx->channel_layout = AV_CH_LAYOUT_STEREO;&#xA;            pOutputCodecCtx->channels = av_get_channel_layout_nb_channels(pOutputCodecCtx->channel_layout);&#xA;&#xA;        }&#xA;        pOutputCodecCtx->sample_fmt = pAudioStream->codec->codec->sample_fmts[0];&#xA;        AVRational time_base={1, pAudioStream->codec->sample_rate};&#xA;        pAudioStream->time_base = time_base;&#xA;        //audioCodecCtx->time_base = time_base;&#xA;&#xA;        pOutputCodecCtx->codec_tag = 0;  &#xA;        if (pFormatCtx_Out->oformat->flags &amp; AVFMT_GLOBALHEADER)  &#xA;            pOutputCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;&#xA;&#xA;        if (avcodec_open2(pOutputCodecCtx, pOutputCodecCtx->codec, 0) &lt; 0)&#xA;        {&#xA;            printf("编码器打开失败,退出程序\n");&#xA;            return -1;&#xA;        }&#xA;    }&#xA;&#xA;    if (!(pFormatCtx_Out->oformat->flags &amp; AVFMT_NOFILE))&#xA;    {&#xA;        if(avio_open(&amp;pFormatCtx_Out->pb, outFileName, AVIO_FLAG_WRITE) &lt; 0)&#xA;        {&#xA;            printf("can not open output file handle!\n");&#xA;            return -1;&#xA;        }&#xA;    }&#xA;&#xA;    if(avformat_write_header(pFormatCtx_Out, NULL) &lt; 0)&#xA;    {&#xA;        printf("can not write the header of the output file!\n");&#xA;        return -1;&#xA;    }&#xA;&#xA;    return 0;&#xA;}&#xA;&#xA;int _tmain(int argc, _TCHAR* argv[])&#xA;{&#xA;    av_register_all();&#xA;    avdevice_register_all();&#xA;    if (OpenVideoCapture() &lt; 0)&#xA;    {&#xA;        return -1;&#xA;    }&#xA;    if (OpenAudioCapture() &lt; 0)&#xA;    {&#xA;        return -1;&#xA;    }&#xA;    if (OpenOutPut() &lt; 0)&#xA;    {&#xA;        return -1;&#xA;    }&#xA;//  int fps;&#xA;    /*printf("输入帧率:");&#xA;    scanf_s("%d",&amp;fps);&#xA;    if ( NULL == fps)&#xA;    {&#xA;        fps = 10;&#xA;    }*/&#xA;&#xA;    InitializeCriticalSection(&amp;VideoSection);&#xA;    InitializeCriticalSection(&amp;AudioSection);&#xA;&#xA;    AVFrame *picture = av_frame_alloc();&#xA;    int size = avpicture_get_size(pFormatCtx_Out->streams[VideoIndex]->codec->pix_fmt, &#xA;        pFormatCtx_Out->streams[VideoIndex]->codec->width, pFormatCtx_Out->streams[VideoIndex]->codec->height);&#xA;    picture_buf = new uint8_t[size];&#xA;&#xA;    avpicture_fill((AVPicture *)picture, picture_buf, &#xA;        pFormatCtx_Out->streams[VideoIndex]->codec->pix_fmt, &#xA;        pFormatCtx_Out->streams[VideoIndex]->codec->width, &#xA;        pFormatCtx_Out->streams[VideoIndex]->codec->height);&#xA;&#xA;&#xA;&#xA;    //star cap screen thread&#xA;    CreateThread( NULL, 0, ScreenCapThreadProc, 0, 0, NULL);&#xA;    //star cap audio thread&#xA;    CreateThread( NULL, 0, AudioCapThreadProc, 0, 0, NULL);&#xA;    int64_t cur_pts_v=0,cur_pts_a=0;&#xA;    int VideoFrameIndex = 0, AudioFrameIndex = 0;&#xA;&#xA;    while(1)&#xA;    {&#xA;        if (_kbhit() != 0 &amp;&amp; bCap)&#xA;        {&#xA;            bCap = false;&#xA;            Sleep(2000);&#xA;        }&#xA;        if (fifo_audio &amp;&amp; fifo_video)&#xA;        {&#xA;            int sizeAudio = av_audio_fifo_size(fifo_audio);&#xA;            int sizeVideo = av_fifo_size(fifo_video);&#xA;            //缓存数据写完就结束循环&#xA;            if (av_audio_fifo_size(fifo_audio) &lt;= pFormatCtx_Out->streams[AudioIndex]->codec->frame_size &amp;&amp; &#xA;                av_fifo_size(fifo_video) &lt;= frame_size &amp;&amp; !bCap)&#xA;            {&#xA;                break;&#xA;            }&#xA;        }&#xA;&#xA;        if(av_compare_ts(cur_pts_v, pFormatCtx_Out->streams[VideoIndex]->time_base, &#xA;                         cur_pts_a,pFormatCtx_Out->streams[AudioIndex]->time_base) &lt;= 0)&#xA;        {&#xA;            if (av_fifo_size(fifo_video) &lt; frame_size &amp;&amp; !bCap)&#xA;            {&#xA;                cur_pts_v = 0x7fffffffffffffff;&#xA;            }&#xA;            if(av_fifo_size(fifo_video) >= size)&#xA;            {&#xA;                EnterCriticalSection(&amp;VideoSection);&#xA;                av_fifo_generic_read(fifo_video, picture_buf, size, NULL); //将数据从avfifobuffer馈送到用户提供的回调。&#xA;                LeaveCriticalSection(&amp;VideoSection);&#xA;&#xA;                avpicture_fill((AVPicture *)picture, picture_buf,&#xA;                    pFormatCtx_Out->streams[VideoIndex]->codec->pix_fmt,&#xA;                    pFormatCtx_Out->streams[VideoIndex]->codec->width,&#xA;                    pFormatCtx_Out->streams[VideoIndex]->codec->height); //根据指定的图像参数和提供的图像数据缓冲区设置图片字段。&#xA;&#xA;                //pts = n * ((1 / timbase)/ fps);&#xA;                //picture->pts = VideoFrameIndex * ((pFormatCtx_Video->streams[0]->time_base.den / pFormatCtx_Video->streams[0]->time_base.num) / 24);&#xA;                picture->pts = VideoFrameIndex * ((outVideoCodecCtx->time_base.den * 100000 / outVideoCodecCtx->time_base.num) / 180);&#xA;&#xA;                int got_picture = 0;&#xA;                AVPacket pkt;&#xA;                av_init_packet(&amp;pkt);&#xA;&#xA;                pkt.data = NULL;&#xA;                pkt.size = 0;&#xA;                //从帧中获取输入的原始视频数据&#xA;                int ret = avcodec_encode_video2(pFormatCtx_Out->streams[VideoIndex]->codec, &amp;pkt, picture, &amp;got_picture);&#xA;                if(ret &lt; 0)&#xA;                {&#xA;                    continue;&#xA;                }&#xA;&#xA;                if (got_picture==1)&#xA;                {&#xA;                    pkt.stream_index = VideoIndex;&#xA;                    /*int count = 1;&#xA;                    pkt.pts = pkt.dts = count * ((pFormatCtx_Video->streams[0]->time_base.den / pFormatCtx_Video->streams[0]->time_base.num) / 15);&#xA;                    count&#x2B;&#x2B;;*/&#xA;&#xA;                    //x = pts * (timebase1.num / timebase1.den )* (timebase2.den / timebase2.num);&#xA;&#xA;                    pkt.pts = av_rescale_q_rnd(pkt.pts, pFormatCtx_Video->streams[0]->time_base, &#xA;                        pFormatCtx_Out->streams[VideoIndex]->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));  &#xA;                    pkt.dts = av_rescale_q_rnd(pkt.dts,  pFormatCtx_Video->streams[0]->time_base, &#xA;                        pFormatCtx_Out->streams[VideoIndex]->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX)); &#xA;&#xA;&#xA;                    pkt.duration = ((pFormatCtx_Out->streams[0]->time_base.den / pFormatCtx_Out->streams[0]->time_base.num) / 60);&#xA;                    //pkt.duration = 1000/60;&#xA;                    //pkt.pts = pkt.dts = Count * (ofmt_ctx->streams[stream_index]->time_base.den) /ofmt_ctx->streams[stream_index]->time_base.num / 10;&#xA;&#xA;                    //Count&#x2B;&#x2B;;&#xA;&#xA;&#xA;                    cur_pts_v = pkt.pts;&#xA;&#xA;                    ret = av_interleaved_write_frame(pFormatCtx_Out, &amp;pkt);&#xA;                    //delete[] pkt.data;&#xA;                    av_free_packet(&amp;pkt);&#xA;                }&#xA;                VideoFrameIndex&#x2B;&#x2B;;&#xA;            }&#xA;        }&#xA;        else&#xA;        {&#xA;            if (NULL == fifo_audio)&#xA;            {&#xA;                continue;//还未初始化fifo&#xA;            }&#xA;            if (av_audio_fifo_size(fifo_audio) &lt; pFormatCtx_Out->streams[AudioIndex]->codec->frame_size &amp;&amp; !bCap)&#xA;            {&#xA;                cur_pts_a = 0x7fffffffffffffff;&#xA;            }&#xA;            if(av_audio_fifo_size(fifo_audio) >= &#xA;                (pFormatCtx_Out->streams[AudioIndex]->codec->frame_size > 0 ? pFormatCtx_Out->streams[AudioIndex]->codec->frame_size : 1024))&#xA;            {&#xA;                AVFrame *frame;&#xA;                frame = av_frame_alloc();&#xA;                frame->nb_samples = pFormatCtx_Out->streams[AudioIndex]->codec->frame_size>0 ? pFormatCtx_Out->streams[AudioIndex]->codec->frame_size: 1024;&#xA;                frame->channel_layout = pFormatCtx_Out->streams[AudioIndex]->codec->channel_layout;&#xA;                frame->format = pFormatCtx_Out->streams[AudioIndex]->codec->sample_fmt;&#xA;                frame->sample_rate = pFormatCtx_Out->streams[AudioIndex]->codec->sample_rate;&#xA;                av_frame_get_buffer(frame, 0);&#xA;&#xA;                EnterCriticalSection(&amp;AudioSection);&#xA;                av_audio_fifo_read(fifo_audio, (void **)frame->data, &#xA;                    (pFormatCtx_Out->streams[AudioIndex]->codec->frame_size > 0 ? pFormatCtx_Out->streams[AudioIndex]->codec->frame_size : 1024));&#xA;                LeaveCriticalSection(&amp;AudioSection);&#xA;&#xA;                AVPacket pkt_out;&#xA;                av_init_packet(&amp;pkt_out);&#xA;                int got_picture = -1;&#xA;                pkt_out.data = NULL;&#xA;                pkt_out.size = 0;&#xA;&#xA;                frame->pts = AudioFrameIndex * pFormatCtx_Out->streams[AudioIndex]->codec->frame_size;&#xA;                if (avcodec_encode_audio2(pFormatCtx_Out->streams[AudioIndex]->codec, &amp;pkt_out, frame, &amp;got_picture) &lt; 0)&#xA;                {&#xA;                    printf("can not decoder a frame");&#xA;                }&#xA;                av_frame_free(&amp;frame);&#xA;                if (got_picture) &#xA;                {&#xA;                    pkt_out.stream_index = AudioIndex;&#xA;                    pkt_out.pts = AudioFrameIndex * pFormatCtx_Out->streams[AudioIndex]->codec->frame_size;&#xA;                    pkt_out.dts = AudioFrameIndex * pFormatCtx_Out->streams[AudioIndex]->codec->frame_size;&#xA;                    pkt_out.duration = pFormatCtx_Out->streams[AudioIndex]->codec->frame_size;&#xA;&#xA;                    cur_pts_a = pkt_out.pts;&#xA;&#xA;                    int ret = av_interleaved_write_frame(pFormatCtx_Out, &amp;pkt_out);&#xA;                    av_free_packet(&amp;pkt_out);&#xA;                }&#xA;                AudioFrameIndex&#x2B;&#x2B;;&#xA;            }&#xA;        }&#xA;    }&#xA;&#xA;    delete[] picture_buf;&#xA;&#xA;    av_fifo_free(fifo_video);&#xA;    av_audio_fifo_free(fifo_audio);&#xA;&#xA;    av_write_trailer(pFormatCtx_Out);&#xA;&#xA;    avio_close(pFormatCtx_Out->pb);&#xA;    avformat_free_context(pFormatCtx_Out);&#xA;&#xA;    if (pFormatCtx_Video != NULL)&#xA;    {&#xA;        avformat_close_input(&amp;pFormatCtx_Video);&#xA;        pFormatCtx_Video = NULL;&#xA;    }&#xA;    if (pFormatCtx_Audio != NULL)&#xA;    {&#xA;        avformat_close_input(&amp;pFormatCtx_Audio);&#xA;        pFormatCtx_Audio = NULL;&#xA;    }&#xA;&#xA;    return 0;&#xA;}&#xA;&#xA;DWORD WINAPI ScreenCapThreadProc( LPVOID lpParam )&#xA;{&#xA;    AVPacket packet;&#xA;    int got_picture;&#xA;    AVFrame *pFrame;&#xA;    pFrame=av_frame_alloc();&#xA;&#xA;    AVFrame *picture = av_frame_alloc();&#xA;    int size = avpicture_get_size(pFormatCtx_Out->streams[VideoIndex]->codec->pix_fmt, &#xA;        pFormatCtx_Out->streams[VideoIndex]->codec->width, &#xA;        pFormatCtx_Out->streams[VideoIndex]->codec->height);&#xA;&#xA;    avpicture_fill((AVPicture *)picture, picture_buf, &#xA;        pFormatCtx_Out->streams[VideoIndex]->codec->pix_fmt, &#xA;        pFormatCtx_Out->streams[VideoIndex]->codec->width, &#xA;        pFormatCtx_Out->streams[VideoIndex]->codec->height);&#xA;&#xA;    FILE *p = NULL;&#xA;    p = fopen("proc_test.yuv", "wb&#x2B;");&#xA;    av_init_packet(&amp;packet);&#xA;    int height = pFormatCtx_Out->streams[VideoIndex]->codec->height;&#xA;    int width = pFormatCtx_Out->streams[VideoIndex]->codec->width;&#xA;    int y_size=height*width;&#xA;    while(bCap)&#xA;    {&#xA;        packet.data = NULL;&#xA;        packet.size = 0;&#xA;        if (av_read_frame(pFormatCtx_Video, &amp;packet) &lt; 0)&#xA;        {&#xA;            continue;&#xA;        }&#xA;        if(packet.stream_index == 0)&#xA;        {&#xA;            if (avcodec_decode_video2(pCodecCtx_Video, pFrame, &amp;got_picture, &amp;packet) &lt; 0)&#xA;            {&#xA;                printf("Decode Error.(解码错误)\n");&#xA;                continue;&#xA;            }&#xA;            if (got_picture)&#xA;            {&#xA;                sws_scale(img_convert_ctx, &#xA;                    (const uint8_t* const*)pFrame->data,&#xA;                    pFrame->linesize, &#xA;                    0, &#xA;                    pFormatCtx_Out->streams[VideoIndex]->codec->height,&#xA;                    picture->data,&#xA;                    picture->linesize);&#xA;&#xA;                if (av_fifo_space(fifo_video) >= size)&#xA;                {&#xA;                    EnterCriticalSection(&amp;VideoSection);                    &#xA;                    av_fifo_generic_write(fifo_video, picture->data[0], y_size, NULL);&#xA;                    av_fifo_generic_write(fifo_video, picture->data[1], y_size/4, NULL);&#xA;                    av_fifo_generic_write(fifo_video, picture->data[2], y_size/4, NULL);&#xA;                    LeaveCriticalSection(&amp;VideoSection);&#xA;                }&#xA;            }&#xA;        }&#xA;        av_free_packet(&amp;packet);&#xA;    }&#xA;    av_frame_free(&amp;pFrame);&#xA;    av_frame_free(&amp;picture);&#xA;    return 0;&#xA;}&#xA;&#xA;DWORD WINAPI AudioCapThreadProc( LPVOID lpParam )&#xA;{&#xA;    AVPacket pkt;&#xA;    AVFrame *frame;&#xA;    frame = av_frame_alloc();&#xA;    int gotframe;&#xA;    while(bCap)&#xA;    {&#xA;        pkt.data = NULL;&#xA;        pkt.size = 0;&#xA;        if(av_read_frame(pFormatCtx_Audio,&amp;pkt) &lt; 0)&#xA;        {&#xA;            continue;&#xA;        }&#xA;&#xA;        if (avcodec_decode_audio4(pFormatCtx_Audio->streams[0]->codec, frame, &amp;gotframe, &amp;pkt) &lt; 0)&#xA;        {&#xA;            av_frame_free(&amp;frame);&#xA;            printf("can not decoder a frame");&#xA;            break;&#xA;        }&#xA;        av_free_packet(&amp;pkt);&#xA;&#xA;        if (!gotframe)&#xA;        {&#xA;            printf("没有获取到数据,继续下一次");&#xA;            continue;&#xA;        }&#xA;&#xA;        if (NULL == fifo_audio)&#xA;        {&#xA;            fifo_audio = av_audio_fifo_alloc(pFormatCtx_Audio->streams[0]->codec->sample_fmt, &#xA;                pFormatCtx_Audio->streams[0]->codec->channels, 30 * frame->nb_samples);&#xA;        }&#xA;&#xA;        int buf_space = av_audio_fifo_space(fifo_audio);&#xA;        if (av_audio_fifo_space(fifo_audio) >= frame->nb_samples)&#xA;        {&#xA;            EnterCriticalSection(&amp;AudioSection);&#xA;            av_audio_fifo_write(fifo_audio, (void **)frame->data, frame->nb_samples);&#xA;            LeaveCriticalSection(&amp;AudioSection);&#xA;        }&#xA;    }&#xA;    av_frame_free(&amp;frame);&#xA;    return 0;&#xA;}&#xA;

    &#xA;&#xA;

    Maybe there is another way to calculate PTS and DTS

    &#xA;&#xA;

    I hope whatever the frame rate is,video playback speed is right.Not too fast or too slow.

    &#xA;

  • Q&A : An interview with Matomo founder, Matthieu Aubry

    20 novembre 2018, par Joselyn Khor — About, Community

    Hey everyone ! Joselyn here. As always the views of our community remain top of mind. So to make sure you guys know the thinking behind these new projects, we reached out to Matomo’s founder, Matthieu, to ask questions you might want answered. Please check it out below !

    Hi guys, it’s Matthieu ! Here to answer some questions about the rebrand and the future of Matomo and Innocraft.

    What’s upcoming ?

    We’ve been busy implementing our rebrand into all aspects of Matomo and there’s also our new website, which is launching today ! The new website will help people better understand what Matomo is and how they can benefit from using modern web analytics.

    Why was Matomo and Innocraft brought onto one website ?

    In the past the separation caused a bit of confusion so we’re taking this as a chance to unite both the business brand, Innocraft and community brand, Matomo, on one website. Putting our focus on one brand, Matomo, makes it easier for people to see us with fresh eyes. We have a community side as well as a business side and while the community is still incredibly important to us, we find we have a powerful analytics tool that is capable of helping businesses too.

    Is Matomo becoming commercial or turning corporate ?

    No. nothing is changing. Matomo is still an open-source project and community. Although we’ll have a pricing page and “start free trial” on the new website brought over from Innocraft.cloud, the Matomo community will still play the biggest part on the Matomo website. We have dedicated sections focused on Community and On-Premise.

    The rebrand exercise helped us gain a refreshed perspective. After reflecting on how far we’ve come, we can feel more confident about Matomo Analytics itself as a platform. We believe it’s a great chance to bring that confidence into the brand and vision. We are proud that it’s an awesome open-source platform and at the same time it’s also powerful as a tool for businesses.

    Why is there no ‘download for free’ button on the homepage ?

     

    Matomo CTA simplified
    We feel many users coming to the site will get confused about our hosting options (Cloud and On-Premise) which is something you don’t usually consider when choosing an analytics tool.

    The reason for us to not have that button is when people see a “download for free” button on the homepage next to a “try it for free” button, it creates confusion. For those who do choose to download Matomo often become confused when they are left with a .zip file unaware how to install it and the technical requirements of self-hosting. We feel presenting our users with the simplest installation option first will give them the best chance possible to try Matomo to its full potential, without cost.

    And you can still find the link to Download Matomo in the footer of each page.

     

    Is Matomo still free to download and have forever ?

    Absolutely. The free open-source download can be found on the On-Premise section of the website, or download Matomo here.

    Why is it important to have a business behind the project ?

    There’s the reality that we have to make money in order for the Matomo project to survive … and thrive. The reason we still need a business side (Innocraft) is to fund and sustain the Matomo project. Whenever people purchase premium features, this helps finance the development of Matomo for our community.

    Because of the business we’re able to continually maintain and develop Matomo for you guys as well as future users. For example, the next release Matomo 3.8.0 is already mostly developed and will bring lots of interesting features too, like the two-factor authentication, Brute Force Protection, failed tracking requests reporting, lots of JavaScript tracker improvements, a new total summary row below reports, and many more security fixes, bug fixes, and other new features.

    So we see a business being very helpful in supporting our open-source community. Without a business side, our free, open-source project would not be able to survive.

    How will you protect the Matomo project ?

    We’ve ensured the Matomo project will be protected for the future as we wish to turn it into a not-for-profit foundation.

    We’ve also got a safeguard where the open-source code will stay under a GPL license forever. This is so we can guarantee, that no matter what happens, the Matomo project itself will stay completely free software.

    Is there a way for people to help ?

    There are heaps of ways to help ! You can help other Matomo users in the forums, contribute to fixes on GitHub, leave a great review (e.g. alternativeTo), help look for bugs with our Security Bounty Programme or participate and spread the word about Matomo in our community social media pages – Mastodon, Facebook, Twitter. Telling your friends about us would be very helpful too !

    What’s planned for the future ?
    We’ve worked hard to become the #1 open-source analytics platform (1.4 million websites use Matomo today), but now we need to empower even more individuals and businesses to take back control of their own data.

    Showing our community that we have a powerful platform is crucial, but alongside that our values are what define us. User privacy is still of utmost importance and we’re here to make it known that power needs to rest in the hands of people and not large corporations.

    You can rest easy knowing you’re doing your part in using trustworthy and dependable tools. By joining many other companies who are growing this movement to decentralise the Internet, we can build a safer, online world together.

    Join this analytics revolution and let us know what you think about Matomo !