Recherche avancée

Médias (91)

Autres articles (97)

  • MediaSPIP 0.1 Beta version

    25 avril 2011, par

    MediaSPIP 0.1 beta is the first version of MediaSPIP proclaimed as "usable".
    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 (...)

  • HTML5 audio and video support

    13 avril 2011, par

    MediaSPIP uses HTML5 video and audio tags to play multimedia files, taking advantage of the latest W3C innovations supported by modern browsers.
    The MediaSPIP player used has been created specifically for MediaSPIP and can be easily adapted to fit in with a specific theme.
    For older browsers the Flowplayer flash fallback is used.
    MediaSPIP allows for media playback on major mobile platforms with the above (...)

  • ANNEXE : Les plugins utilisés spécifiquement pour la ferme

    5 mars 2010, par

    Le site central/maître de la ferme a besoin d’utiliser plusieurs plugins supplémentaires vis à vis des canaux pour son bon fonctionnement. le plugin Gestion de la mutualisation ; le plugin inscription3 pour gérer les inscriptions et les demandes de création d’instance de mutualisation dès l’inscription des utilisateurs ; le plugin verifier qui fournit une API de vérification des champs (utilisé par inscription3) ; le plugin champs extras v2 nécessité par inscription3 (...)

Sur d’autres sites (10082)

  • How to create a custom theme in Piwik – Introducing the Piwik Platform

    23 août 2014, par Thomas Steur — Development

    This is the start of a new blog series where we introduce the capabilities of the Piwik platform. You’ll learn how to write custom plugins & themes, how to use our HTTP APIs and more.

    We have been greatly simplifying our APIs over the last year focusing primarily on one design principle :

    The complexity of our API should never exceed the complexity of your use case.

    In other words, if you have a simple use for our API, we want it to be simple for you to accomplish it. If you have a complex, big, hairy, change-the-world idea, then maybe we can’t make it simple for you to accomplish it, but we want it to be possible.

    Over the next weeks and months you will learn what exactly we mean by this and how we accomplished it.

    FYI, don’t worry if you’re currently using our APIs, we keep them backwards compatible and we announce breaking changes in our platform changelog.

    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.
    • And if you want, generate some test data : ./console visitorgenerator:generate-visits --idsite=1 --limit-fake-visits=600. This can take a while and requires the VisitorGenerator plugin from the Marketplace.

    Let’s start creating our own theme

    We start by using the Piwik Console to create a blank theme :

    ./console generate:theme

    The command will ask you to enter a name, description and version number for your theme. I will simply use “CustomTheme” as the name of the theme. There should now be a folder plugins/CustomTheme which contains some files to get you started easily.

    Before we modify our theme, we have to activate it by visiting the Settings => Themes admin page in our Piwik installation, or alternatively by running the command ./console core:plugin activate YourCustomTheme. If the theme is not activated, we won’t see any changes.

    Theme Contents

    The most important files in our theme are plugins/CustomTheme/stylesheets/theme.less, plugins/CustomTheme/stylesheets/_colors.less and plugins/CustomTheme/stylesheets/_variables.less :

    • theme.less is the file that will be included when your theme is activated. In this file you would include other stylesheet files and overwrite CSS styles.
    • _colors.less contains many less variables allowing you to easily change the colors Piwik uses.
    • _variables.less contains currently only one variable to change the font family. More variables will be added in the future. Note : This is a new feature and the file will be only there in case you have installed Piwik using Git or at least Piwik 2.6.0.

    Changing the font family

    To change the font family simply overwrite the variable @theme-fontFamily-base: Verdana, sans-serif; in _variables.less. That’s it.

    Changing colors

    To change a color, uncomment the less variables of the colors you want to change in _colors.less. I will shortly explain some of them. Usually changing only these colors will be enough to adjust Piwik’s look to your corporate design or to create a look that pleases you :

    @theme-color-brand:                    #d4291f; // The Piwik red which is for instance used in the menu, it also defines the color of buttons, the little arrows and more
    @theme-color-brand-contrast:           #ffffff; // Contrast color to the Piwik red. Usually you need to change it only in case you define a light brand color. For instance to change the text color of buttons
    @theme-color-link:                     #1e93d1; // The link color which is usually a light blue

    @theme-color-widget-title-text:        #0d0d0d; // The text and background color of the header of a widget (Dashboard)
    @theme-color-widget-title-background:  #f2f2f2;

    @theme-color-menu-contrast-text:       #666666; // The text color of a menu item in the reporting sub menu and the admin menu
    @theme-color-menu-contrast-textActive: #0d0d0d; // The text color of an active menu item
    @theme-color-menu-contrast-background: #f2f2f2; // The background color of a menu item

    @graph-colors-data-series[1-8]:        #000000; // The different colors used in graphs

    Making the change visible

    To make a color or font change actually visible when you reload a page in Piwik you will have to delete the compiled CSS file after each change like this :

    rm tmp/assets/asset_manager_global_css.css

    Publishing your Theme on the Marketplace

    In case you want to share your theme with other Piwik users you can do this by pushing your theme to GitHub and creating a tag. Easy as that. Read more about how to distribute a theme.

    Advanced features

    Isn’t it easy to create a custom theme ? All we had to do is to change some less variables. We never even created a file ! Of course, based on our API design principle, you can accomplish more if you want. For instance, you can change icons, CSS stylesheets, templates and more.

    For further customising your Piwik, you can even change the logo and favicon in the Settings => General settings page.

    Would you like to know more about theming ? Go to our Theme guide in the Piwik Developer Zone.

    If you have any feedback regarding our APIs or our guides in the Developer Zone feel free to send it to us.

    PS : see also this related FAQ : How do I White Label Piwik ?

  • How to create a custom theme in Piwik – Introducing the Piwik Platform

    23 août 2014, par Thomas Steur — Development

    This is the start of a new blog series where we introduce the capabilities of the Piwik platform. You’ll learn how to write custom plugins & themes, how to use our HTTP APIs and more.

    We have been greatly simplifying our APIs over the last year focusing primarily on one design principle :

    The complexity of our API should never exceed the complexity of your use case.

    In other words, if you have a simple use for our API, we want it to be simple for you to accomplish it. If you have a complex, big, hairy, change-the-world idea, then maybe we can’t make it simple for you to accomplish it, but we want it to be possible.

    Over the next weeks and months you will learn what exactly we mean by this and how we accomplished it.

    FYI, don’t worry if you’re currently using our APIs, we keep them backwards compatible and we announce breaking changes in our platform changelog.

    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.
    • And if you want, generate some test data : ./console visitorgenerator:generate-visits --idsite=1 --limit-fake-visits=600. This can take a while and requires the VisitorGenerator plugin from the Marketplace.

    Let’s start creating our own theme

    We start by using the Piwik Console to create a blank theme :

    ./console generate:theme

    The command will ask you to enter a name, description and version number for your theme. I will simply use “CustomTheme” as the name of the theme. There should now be a folder plugins/CustomTheme which contains some files to get you started easily.

    Before we modify our theme, we have to activate it by visiting the Settings => Themes admin page in our Piwik installation, or alternatively by running the command ./console core:plugin activate YourCustomTheme. If the theme is not activated, we won’t see any changes.

    Theme Contents

    The most important files in our theme are plugins/CustomTheme/stylesheets/theme.less, plugins/CustomTheme/stylesheets/_colors.less and plugins/CustomTheme/stylesheets/_variables.less :

    • theme.less is the file that will be included when your theme is activated. In this file you would include other stylesheet files and overwrite CSS styles.
    • _colors.less contains many less variables allowing you to easily change the colors Piwik uses.
    • _variables.less contains currently only one variable to change the font family. More variables will be added in the future. Note : This is a new feature and the file will be only there in case you have installed Piwik using Git or at least Piwik 2.6.0.

    Changing the font family

    To change the font family simply overwrite the variable @theme-fontFamily-base: Verdana, sans-serif; in _variables.less. That’s it.

    Changing colors

    To change a color, uncomment the less variables of the colors you want to change in _colors.less. I will shortly explain some of them. Usually changing only these colors will be enough to adjust Piwik’s look to your corporate design or to create a look that pleases you :

    @theme-color-brand:                    #d4291f; // The Piwik red which is for instance used in the menu, it also defines the color of buttons, the little arrows and more
    @theme-color-brand-contrast:           #ffffff; // Contrast color to the Piwik red. Usually you need to change it only in case you define a light brand color. For instance to change the text color of buttons
    @theme-color-link:                     #1e93d1; // The link color which is usually a light blue

    @theme-color-widget-title-text:        #0d0d0d; // The text and background color of the header of a widget (Dashboard)
    @theme-color-widget-title-background:  #f2f2f2;

    @theme-color-menu-contrast-text:       #666666; // The text color of a menu item in the reporting sub menu and the admin menu
    @theme-color-menu-contrast-textActive: #0d0d0d; // The text color of an active menu item
    @theme-color-menu-contrast-background: #f2f2f2; // The background color of a menu item

    @graph-colors-data-series[1-8]:        #000000; // The different colors used in graphs

    Making the change visible

    To make a color or font change actually visible when you reload a page in Piwik you will have to delete the compiled CSS file after each change like this :

    rm tmp/assets/asset_manager_global_css.css

    Publishing your Theme on the Marketplace

    In case you want to share your theme with other Piwik users you can do this by pushing your theme to GitHub and creating a tag. Easy as that. Read more about how to distribute a theme.

    Advanced features

    Isn’t it easy to create a custom theme ? All we had to do is to change some less variables. We never even created a file ! Of course, based on our API design principle, you can accomplish more if you want. For instance, you can change icons, CSS stylesheets, templates and more.

    For further customising your Piwik, you can even change the logo and favicon in the Settings => General settings page.

    Would you like to know more about theming ? Go to our Theme guide in the Piwik Developer Zone.

    If you have any feedback regarding our APIs or our guides in the Developer Zone feel free to send it to us.

    PS : see also this related FAQ : How do I White Label Piwik ?

  • Play video using mse (media source extension) in google chrome

    23 août 2019, par liyuqihxc

    I’m working on a project that convert rtsp stream (ffmpeg) and play it on the web page (signalr + mse).

    So far it works pretty much as I expected on the latest version of edge and firefox, but not chrome.

    here’s the code

    public class WebmMediaStreamContext
    {
       private Process _ffProcess;
       private readonly string _cmd;
       private byte[] _initSegment;
       private Task _readMediaStreamTask;
       private CancellationTokenSource _cancellationTokenSource;

       private const string _CmdTemplate = "-i {0} -c:v libvpx -tile-columns 4 -frame-parallel 1 -keyint_min 90 -g 90 -f webm -dash 1 pipe:";

       public static readonly byte[] ClusterStart = { 0x1F, 0x43, 0xB6, 0x75, 0x01, 0x00, 0x00, 0x00 };

       public event EventHandler<clusterreadyeventargs> ClusterReadyEvent;

       public WebmMediaStreamContext(string rtspFeed)
       {
           _cmd = string.Format(_CmdTemplate, rtspFeed);
       }

       public async Task StartConverting()
       {
           if (_ffProcess != null)
               throw new InvalidOperationException();

           _ffProcess = new Process();
           _ffProcess.StartInfo = new ProcessStartInfo
           {
               FileName = "ffmpeg/ffmpeg.exe",
               Arguments = _cmd,
               UseShellExecute = false,
               CreateNoWindow = true,
               RedirectStandardOutput = true
           };
           _ffProcess.Start();

           _initSegment = await ParseInitSegmentAndStartReadMediaStream();
       }

       public byte[] GetInitSegment()
       {
           return _initSegment;
       }

       // Find the first cluster, and everything before it is the InitSegment
       private async Task ParseInitSegmentAndStartReadMediaStream()
       {
           Memory<byte> buffer = new byte[10 * 1024];
           int length = 0;
           while (length != buffer.Length)
           {
               length += await _ffProcess.StandardOutput.BaseStream.ReadAsync(buffer.Slice(length));
               int cluster = buffer.Span.IndexOf(ClusterStart);
               if (cluster >= 0)
               {
                   _cancellationTokenSource = new CancellationTokenSource();
                   _readMediaStreamTask = new Task(() => ReadMediaStreamProc(buffer.Slice(cluster, length - cluster).ToArray(), _cancellationTokenSource.Token), _cancellationTokenSource.Token, TaskCreationOptions.LongRunning);
                   _readMediaStreamTask.Start();
                   return buffer.Slice(0, cluster).ToArray();
               }
           }

           throw new InvalidOperationException();
       }

       private void ReadMoreBytes(Span<byte> buffer)
       {
           int size = buffer.Length;
           while (size > 0)
           {
               int len = _ffProcess.StandardOutput.BaseStream.Read(buffer.Slice(buffer.Length - size));
               size -= len;
           }
       }

       // Parse every single cluster and fire ClusterReadyEvent
       private void ReadMediaStreamProc(byte[] bytesRead, CancellationToken cancel)
       {
           Span<byte> buffer = new byte[5 * 1024 * 1024];
           bytesRead.CopyTo(buffer);
           int bufferEmptyIndex = bytesRead.Length;

           do
           {
               if (bufferEmptyIndex &lt; ClusterStart.Length + 4)
               {
                   ReadMoreBytes(buffer.Slice(bufferEmptyIndex, 1024));
                   bufferEmptyIndex += 1024;
               }

               int clusterDataSize = BitConverter.ToInt32(
                   buffer.Slice(ClusterStart.Length, 4)
                   .ToArray()
                   .Reverse()
                   .ToArray()
               );
               int clusterSize = ClusterStart.Length + 4 + clusterDataSize;
               if (clusterSize > buffer.Length)
               {
                   byte[] newBuffer = new byte[clusterSize];
                   buffer.Slice(0, bufferEmptyIndex).CopyTo(newBuffer);
                   buffer = newBuffer;
               }

               if (bufferEmptyIndex &lt; clusterSize)
               {
                   ReadMoreBytes(buffer.Slice(bufferEmptyIndex, clusterSize - bufferEmptyIndex));
                   bufferEmptyIndex = clusterSize;
               }

               ClusterReadyEvent?.Invoke(this, new ClusterReadyEventArgs(buffer.Slice(0, bufferEmptyIndex).ToArray()));

               bufferEmptyIndex = 0;
           } while (!cancel.IsCancellationRequested);
       }
    }
    </byte></byte></byte></clusterreadyeventargs>

    I use ffmpeg to convert the rtsp stream to vp8 WEBM byte stream and parse it to "Init Segment" (ebml head、info、tracks...) and "Media Segment" (cluster), then send it to browser via signalR

    $(function () {

       var mediaSource = new MediaSource();
       var mimeCodec = 'video/webm; codecs="vp8"';

       var video = document.getElementById('video');

       mediaSource.addEventListener('sourceopen', callback, false);
       function callback(e) {
           var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
           var queue = [];

           sourceBuffer.addEventListener('updateend', function () {
               if (queue.length === 0) {
                   return;
               }

               var base64 = queue[0];
               if (base64.length === 0) {
                   mediaSource.endOfStream();
                   queue.shift();
                   return;
               } else {
                   var buffer = new Uint8Array(atob(base64).split("").map(function (c) {
                       return c.charCodeAt(0);
                   }));
                   sourceBuffer.appendBuffer(buffer);
                   queue.shift();
               }
           }, false);

           var connection = new signalR.HubConnectionBuilder()
               .withUrl("/signalr-video")
               .configureLogging(signalR.LogLevel.Information)
               .build();
           connection.start().then(function () {
               connection.stream("InitVideoReceive")
                   .subscribe({
                       next: function(item) {
                           if (queue.length === 0 &amp;&amp; !!!sourceBuffer.updating) {
                               var buffer = new Uint8Array(atob(item).split("").map(function (c) {
                                   return c.charCodeAt(0);
                               }));
                               sourceBuffer.appendBuffer(buffer);
                               console.log(blockindex++ + " : " + buffer.byteLength);
                           } else {
                               queue.push(item);
                           }
                       },
                       complete: function () {
                           queue.push('');
                       },
                       error: function (err) {
                           console.error(err);
                       }
                   });
           });
       }
       video.src = window.URL.createObjectURL(mediaSource);
    })

    chrome just play the video for 3 5 seconds and then stop for buffering, even though there are plenty of cluster transfered and inserted into SourceBuffer.

    here’s the information in chrome ://media-internals/

    Player Properties :

    render_id: 217
    player_id: 1
    origin_url: http://localhost:52531/
    frame_url: http://localhost:52531/
    frame_title: Home Page
    url: blob:http://localhost:52531/dcb25d89-9830-40a5-ba88-33c13b5c03eb
    info: Selected FFmpegVideoDecoder for video decoding, config: codec: vp8 format: 1 profile: vp8 coded size: [1280,720] visible rect: [0,0,1280,720] natural size: [1280,720] has extra data? false encryption scheme: Unencrypted rotation: 0°
    pipeline_state: kSuspended
    found_video_stream: true
    video_codec_name: vp8
    video_dds: false
    video_decoder: FFmpegVideoDecoder
    duration: unknown
    height: 720
    width: 1280
    video_buffering_state: BUFFERING_HAVE_NOTHING
    for_suspended_start: false
    pipeline_buffering_state: BUFFERING_HAVE_NOTHING
    event: PAUSE

    Log

    Timestamp       Property            Value
    00:00:00 00     origin_url          http://localhost:52531/
    00:00:00 00     frame_url           http://localhost:52531/
    00:00:00 00     frame_title         Home Page
    00:00:00 00     url                 blob:http://localhost:52531/dcb25d89-9830-40a5-ba88-33c13b5c03eb
    00:00:00 00     info                ChunkDemuxer: buffering by DTS
    00:00:00 35     pipeline_state      kStarting
    00:00:15 213    found_video_stream  true
    00:00:15 213    video_codec_name    vp8
    00:00:15 216    video_dds           false
    00:00:15 216    video_decoder       FFmpegVideoDecoder
    00:00:15 216    info                Selected FFmpegVideoDecoder for video decoding, config: codec: vp8 format: 1 profile: vp8 coded size: [1280,720] visible rect: [0,0,1280,720] natural size: [1280,720] has extra data? false encryption scheme: Unencrypted rotation: 0°
    00:00:15 216    pipeline_state      kPlaying
    00:00:15 213    duration            unknown
    00:00:16 661    height              720
    00:00:16 661    width               1280
    00:00:16 665    video_buffering_state       BUFFERING_HAVE_ENOUGH
    00:00:16 665    for_suspended_start         false
    00:00:16 665    pipeline_buffering_state    BUFFERING_HAVE_ENOUGH
    00:00:16 667    pipeline_state      kSuspending
    00:00:16 670    pipeline_state      kSuspended
    00:00:52 759    info                Effective playback rate changed from 0 to 1
    00:00:52 759    event               PLAY
    00:00:52 759    pipeline_state      kResuming
    00:00:52 760    video_dds           false
    00:00:52 760    video_decoder       FFmpegVideoDecoder
    00:00:52 760    info                Selected FFmpegVideoDecoder for video decoding, config: codec: vp8 format: 1 profile: vp8 coded size: [1280,720] visible rect: [0,0,1280,720] natural size: [1280,720] has extra data? false encryption scheme: Unencrypted rotation: 0°
    00:00:52 760    pipeline_state      kPlaying
    00:00:52 793    height              720
    00:00:52 793    width               1280
    00:00:52 798    video_buffering_state       BUFFERING_HAVE_ENOUGH
    00:00:52 798    for_suspended_start         false
    00:00:52 798    pipeline_buffering_state    BUFFERING_HAVE_ENOUGH
    00:00:56 278    video_buffering_state       BUFFERING_HAVE_NOTHING
    00:00:56 295    for_suspended_start         false
    00:00:56 295    pipeline_buffering_state    BUFFERING_HAVE_NOTHING
    00:01:20 717    event               PAUSE
    00:01:33 538    event               PLAY
    00:01:35 94     event               PAUSE
    00:01:55 561    pipeline_state      kSuspending
    00:01:55 563    pipeline_state      kSuspended

    Can someone tell me what’s wrong with my code, or dose chrome require some magic configuration to work ?

    Thanks 

    Please excuse my english :)