Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to enable the media tracking #20

Open
michael-hillmann opened this issue Jan 25, 2021 · 3 comments
Open

How to enable the media tracking #20

michael-hillmann opened this issue Jan 25, 2021 · 3 comments

Comments

@michael-hillmann
Copy link

michael-hillmann commented Jan 25, 2021

Hi, I'm building a video component in NUXT, which runs fine so far. When I want to enable tracking for the video media usage of the media extension of Matomo (I use the cloud installation), we need to call the function "MediaAnalytics::scanForMedia" as described in the Matomo SDK

Here is my component:

<template>
  <div v-if="video.title">
    <video
      id="player"
      :title="video.title"
      :data-matomo-title="video.title"
      class="cld-video-player cld-video-player-skin-dark"
    >
    </video>
  </div>
</template>

<script>
export default {
  probs: {
    video: {
      type: Object,
      required: true
    }
  },
  mounted() {
    if (this.video.title) {
      const cld = cloudinary.Cloudinary.new({
        cloud_name: '<my-cloudinary-space>',
        secure: true
      })
      const player = cld.videoPlayer('player', {
          "fluid": true,
          "controls": true,
          "hideContextMenu": true,
          "posterOptions": {
              "transformation": {
                  "startOffset": this.video.poster_seconds
              }
          }
      })
      const public_id = this.video.video_id.filename
      const start = public_id.indexOf('/videos/') + 1
      const end = public_id.indexOf('.mp4')
      player.source(public_id.substring(start, end), {
          "info": {
              "title": this.video.title,
              "subtitle": this.video.subtitle
          }
      })
      if (this.$matomo) {
        this.$matomo['MediaAnalytics::scanForMedia']()
      }
    }
  }
}
</script>

When enable debug information for [nuxt-matomo], I got the information:

[nuxt-matomo] Delaying call to tracker: MediaAnalytics::scanForMedia

But never the delayed calling as I would expect:

[nuxt-matomo] Calling tracker MediaAnalytics::scanForMedia with args []

Any ideas, what I'm doing wrong?

@pimlie
Copy link
Owner

pimlie commented Jan 31, 2021

@michael-hillmann window.$matomo is a ref to the matomo tracker object (not window._paq), afaik there doesnt exist a MediaAnalytics::scanForMedia method so when matomo is loaded it wont execute that fn because it doesnt exists.

Looking at the Matomo docs Im not entirely sure which method on the tracker you should use though cause I cant find any docs for the media plugin.

@michael-hillmann
Copy link
Author

According to this documentation, I got it managed to result in a working application. Unfortunately, I need to remove the Javascript Proxy from the plugin and put the plugin.js directly in my project. So: far from optimal, but working for now. ;-)

matomo.zip

To get this working, I add the official javascript snippet from matomo.com into my nuxt.config.js like:

import config from './app.config.js'

export default {
  target: 'static',
  head: {
    __dangerouslyDisableSanitizers: ['script'],
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' }
    ],
    script: [
      // asynchronous tracking
      config.MATOMO_SITE_ID ? {
        innerHTML:
          `var _paq = window._paq = window._paq || []; `+
          `_paq.push(["trackPageView"]); ` +
          `_paq.push(["enableLinkTracking"]); ` +
          `(function() { var u="${config.MATOMO_URL}"; ` +
          `_paq.push(["setTrackerUrl", u+"matomo.php"]); ` +
          `_paq.push(["setSiteId", "${config.MATOMO_SITE_ID}"]); ` +
          `var d=document, g=d.createElement("script"), s=d.getElementsByTagName("script")[0]; ` +
          `g.type="text/javascript"; g.async=true; g.src="${config.MATOMO_SRC}"; ` +
          `s.parentNode.insertBefore(g,s); })();`,
        type: 'text/javascript',
        charset: 'utf-8'} : {}
      ]
  },
  // ... snipping irrelevant stuff ...
  plugins: [
    { src: '~plugins/matomo.js', mode: 'client' }
  ],
  // ... snipping irrelevant stuff ...
}

and a configuration file app.config.js:

// development settings
const development = {
  MATOMO_SITE_ID: [your matomo site-id for testing]
}

// production settings
const production = {
  MATOMO_SITE_ID: [your matomo site-id for production]
}

const config = process.env.NODE_ENV=='development' ? development : production

// common settings
export default {
  // analytics url
  MATOMO_SRC: '//cdn.matomo.cloud/[matomo-account].matomo.cloud/matomo.js',
  MATOMO_URL: 'https://[matomo-account].matomo.cloud/',

  // add stage specific settings
  ...config
}

@michael-hillmann
Copy link
Author

michael-hillmann commented Feb 4, 2021

In case someone is interested: my video component is now working fine. I'm using Cloudinary for video hosting and video.js as a video player because this player is supported by Matomo out of the box.

Comments for improvements are welcome!

<template>
  <v-container>
    <v-card>
      <v-card-text class="pa-1">
        <video
          ref="videoPlayer"
          preload="none"
          :title="paragraph.video_title"
          :data-matomo-title="paragraph.video_title"
          aspect-ratio="1"
          class="video-js vjs-fill player-dimensions"
        >
        </video>
      </v-card-text>
    </v-card>
    <div v-if="paragraph.caption != ''">
      <div class="caption font-italic text-center">
        {{ paragraph.caption }}
      </div>
    </div>    
  </v-container>
</template>

<script>
import videojs from 'video.js'

export default {
  name: 'Video',
  props: {
    paragraph: {
      type: Object,
      required: true
    }
  },
  data() {
    return {
      player: null
    }
  },
  methods: {
    getVideo(type) {
      const url = this.paragraph.video_id.filename.replace('.mp4', '.' + type)
      const video = {
        src: url,
        type: "video/" + type
      }
      return video
    },
    getPoster(type) {
      const url = this.paragraph.video_id.filename
        .replace('/upload/','/upload/so_0,h_300,w_500,f_auto,c_limit/')
        .replace('.mp4', '.' + type)
      return url
    }
  },
  mounted() {
    const context = this
    this.player = videojs(this.$refs.videoPlayer, {
      aspectRatio: '9:16',
      responsive: true,
      autoplay: false,
      controls: true,
      sources: [
        this.getVideo('mp4'),
        this.getVideo('webm'),
        this.getVideo('ogg')
      ],
      poster: this.getPoster('jpg') 
    },
    function onPlayerReady() {
      if (window && window._paq) {
      }
    })
  },
  beforeDestroy() {
    if (this.player) {
      this.player.dispose()
    }
  }
}
</script>

<style>
.vjs-poster {
  background-size: cover;
  background-color: #fff;
}
.player-dimensions {
  width: 1920px;
  height: 1080px;
}
.player-dimensions.vjs-fluid {
  padding-top: 56.25%;
}
</style>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants