How can i track ad impression using videojs vast-vpaid plugin?
Ad impression will always be fired when the ad started?
Is there a way to track ads duration events? (first-quartile,second,etc)
Will it be different tracking event for VPAID ads?
This is an example of my code:
</head>
<body>
<video id="example_video_1" class="video-js vjs-default-skin"
controls="" preload="none" width="300" height="300"
poster="http://vjs.zencdn.net/v/oceans.png">
</video>
<script>
var player;
$(document).ready(function() {
player = videojs('example_video_1', {
techOrder: ['html5','flash'],
//autoplay: true,
sources: [{
type: "video/mp4",
src: "http://vjs.zencdn.net/v/oceans.mp4"
}],
plugins: {
vastClient: {
adTagUrl: "http://ssp.lkqd.net/ad?pid=2000&sid=20497&env=3&format=1&width=[WIDTH]&height=[HEIGHT]&dnt=[DO_NOT_TRACK]&output=vast&rnd=[CACHEBUSTER]&pageurl=[URL_ENCODED_PAGEURL]",
adsCancelTimeout: 3000,
adsEnabled: true
}
}
});
player.on('vast.adStart', function () {
});
player.on('vast.contentEnd', function () {
});
});
</script>
</body>
</html>
There are currently two issues open regarding events:
#115 add trigger for quartiles
can a trigger be added for each of the vast quartiles.
#194 Quartiles and Impression events while playing Vast/Vpaid (yours)
How do i listen to Quartiles events while playing Vast/Vpaid?
How do i listen to an Impression event?
The plugin handles events internally. Meaning it's not build to trigger each event except for these documented under Plugin events
... with an exception:
Some VPAID events like ...
vpaid.AdVideoFirstQuartile
vpaid.AdVideoMidpoint
vpaid.AdVideoThirdQuartile
are receivable.
VAST events, afaig Nope.
Regarding vast.adStart vs. AdImpression (btw: same for VPAID) you can “emulate” the behaviour if you unregister the event after its first occurrence:
player.on('vast.adStart', function (e) {
// do something ...
player.off('vast.adStart');
});
Specs and the fact that we don't have an vast.impression event telling us why:
2.2.5.4 Impression vs. “Start” Event
Impression tracking URIs should be used to track when the first frame of the ad is displayed. However, an ad may be made up of multiple creative. If the advertiser wants to track when individual ad creative are started in addition to tracking the ad impression, the VAST response should include a “start” event under the element for the creative to be tracked. See the tracking notes under each relevant ad format in sections 2.3.1 – 2.3.5 for details.
Last but not least, for VAST and VPAID complete events you might want to use vast.adEnd instead of vast.contentEnd
I know the answer is unsatisfying, but it is like it is - at least for now. You might want to implement something yourself. If so, pls share ;)
Have a nice day.
Related
Good day guys!
I need some help regarding the following: I use the following snippet to initialise the Google Tag Manager in my Next.JS application.
_app.js
<Script id={"data-layer-initialization"} strategy={"afterInteractive"}>
{`window.dataLayer = window.dataLayer || []`}
</Script>
<Script id="google-tag-manager" strategy="afterInteractive">
{`(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','${GMT_XXXXX}');`}
</Script>
_document.js
<noscript
dangerouslySetInnerHTML={{
__html: `<iframe src="https://www.googletagmanager.com/ns.html?id=${GMT_ID2}"
height="0" width="0" style="display:none;visibility:hidden"></iframe>`,
}}
/>
I need to push some data layer information regarding the user details (e.g. id) when he has logged in and for this reason i am using the react-gtm-module. I am initialising basically the tag manager using the related gtmId, passing into the dataLayer object the info needed.
useEffect(() => {
TagManager.initialize({
gtmId: GMT_ID2,
dataLayer: {
event: "login",
authenticationMethod: 'email',
userId: userId,
},
});
}, [userId]);
};
From the GTM side, I have turned the information (user ID) into a GTM variable (data layer variable) and then insert the user ID variable in the GA4 configuration tag. When testing into the GTM preview mode, I sign-in but the container loaded after the login event does NOT fire the GA4 configuration tag (not evaluating any tags at all).
What am i missing?
I was expecting the GA4 configuration tag to be fired by the container loaded but nothing happened. In fact, no tags were evaluated at all.
Hi I am looking for tutorial based on Dojo 1.8.
What I am looking for is:- create and instantiate widget pragmatically after dojo page fully loaded and parsed, triggered after dojo/on button. I am not sure of which tutorial in Dojo website, for me to learn.
Please advise.
Thanks in advance.
Clement
There isn't one tutorial that fully answer all your question but the following will be helpful:
Dojo Events tutorial and dojo/on reference
dojo/ready reference
dojo/parser reference
To capture both the full loading of the page and parsing you need to use a combination of dojo/ready and dojo/parser. (I'm assuming that the parsing you refer to is the dojo widget parser, rather than the standard browser parsing of HTML).
To run code after parsing you'll need to add parseOnLoad: false to your dojoConfig and run the parser manually; otherwise, there is no way of capturing when it is complete.
<script type="text/javascript" async="true">
require([
"dojo/ready",
"dojo/parser",
"dojo/on,
"dojo/query"
], function(
ready, parser, on, $
){
ready(function(){
// Only run after the page is fully loaded
parser.parse().then(function(instances){
// Only run after parser has parsed the page
var myButton = $("#myButtonid"); // Find your button
if(myButton.length > 0){ // Check button is found
on(myButton[0], "click", function(evt){
// ... add your code here to create and
// instantiate widget
});
}
});
});
}
</script>
Don't forget that you need to turn off automatic parsing of widgets in you dojoConfig, hence, something like this (in the head):
<script type="text/javascript">
dojoConfig= {
"parseOnLoad": false,
"async": true
// ...other settings
};
</script>
I am looking fore some code allowing me to launch automatically a video after another one.
I'am using the great video.js library, which has a quite complete API. I found some snippet to get an event listener working at the end of the 1st video, but then I cannot launch the second one.
This is working, displaying an alert at the end of the 1st video :
_V_("intro").ready(function(){
this.addEvent("ended", function(){
alert('foo');
});
});
And this is also working, launching a video in fullscreen on page reload :
_V_("leader").ready(function(){
var leader = this;
leader.requestFullScreen();
leader.play();
});
But I can't get the 2nd video launching in fullscreen at the end of 1st video...
Last subtility, I would like to entirely build the 2nd video with javascript, not having to write it and just hiding id with CSS.
Thank you folks !
Elliot
You can simply use the provided 'src' method in the Video.js API, if you want to play a second video right after the first one finishes it would work like this:
_V_("intro").ready(function(){
this.addEvent("ended", function(){
this.src({ type: "video/mp4", src: "http://path/to/second/video.mp4" });
});
});
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I am very new to Sencha Touch framework, want to start with Sencha Touch 2.0 but not able to find any tutorial showing an application built using MVC Pattern and specifically in Sencha Touch version 2.0.
This is probably one of the earliest tutorials so be patient and know that things may change by the final release sees the light of day.
For MVC you're gonna want to set your folder structure first. Something like this:
MyApp
app
controller
model
profile
store
view
touch2
app.js
index.html
Now, let's start with a sample app.
index.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Sample App</title>
<link rel="stylesheet" href="touch2/resources/css/sencha-touch.css" type="text/css" title="senchatouch" id="senchatouch" />
<link rel="stylesheet" href="touch2/resources/css/android.css" type="text/css" title="android" id="android" disabled="true" />
<link rel="stylesheet" href="touch2/resources/css/apple.css" type="text/css" title="apple" id="apple" disabled="true" />
<link rel="stylesheet" href="touch2/resources/css/bb6.css" type="text/css" title="blackberry" id="blackberry" disabled="true" />
<link rel="stylesheet" href="styles/main.css" type="text/css">
<script type="text/javascript" src="touch2/sencha-touch-debug.js"></script>
<script type="text/javascript" src="app.js"></script>
</head>
<body></body>
</html>
app.js
Ext.Loader.setConfig({
enabled : true
});
Ext.application({
name: 'MyApp',
profiles: ['Tablet'],
views: [
// common Tablet & Phone views
],
models: [
],
controllers: [
'Main'
],
launch:function(){
Ext.Viewport.add(Ext.create('MyApp.view.Main'));
//Ext.Viewport.add(Ext.create('MyApp.view.tablet.Main'));
}
});
Good, now you have the two pivotal files in place and Ext.Loader will fetch framework components as needed for easier debugging.
First you set up your app's namespace (MyApp). That means that all your future classes will be defined under MyApp namespace.
Then you have defined the two main profiles. Tablet and Phone. They tell your app how to behave in different environments. Specify as many (or none) here.
Next, you've set up views, models, and controllers that are shared between the two profiles. They don't care whether you're using the app on a phone or a tablet.
Let's continue with our Tablet profile
app/profile/Tablet.js
Ext.define('MyApp.profile.Tablet', {
extend: 'Ext.app.Profile',
config: {
views: [
'Main'
]
},
isActive: function() {
return !Ext.os.is('Phone');
},
launch: function() {
Ext.create('MyApp.view.tablet.Main');
}
});
Pretty self-explanatory. Config object hold your views/models/controllers that are specific to the profile. They won't be used (included) if you're running the app on a smartphone.
isActive method needs to return true or false after evaluating the environment. I specifically said that Tablets are all non-phones. Logically that's incorrect, but I decided to play this way for simplicity. The more correct way would be
return Ext.os.is('Tablet') || Ext.os.is('Desktop');
The final bit of a profile is the launch method. It tells the app what to do when the app is launched in particular profile. MyApp will create the main view in Ext.Viewport.
Note that Ext.Viewport is an instance of Ext.Container that has already been added to DOM on app start.
Let's create our first view. It can be whatever widget you want, and I chose NavigationView.
app/views/Main.js
Ext.define('MyApp.view.Main', {
extend: 'Ext.navigation.View',
config: {
fullscreen : true,
items: [
{
title: 'My Great App'
}
]
}
});
It's fullscreen (100% width&height) and it immediately creates a TitleBar with title My Great App.
Have you noticed that we just defined MyApp.view.Main, but the app is going to expect MyApp.view.tablet.Main? Exactly because I wanted to show how you can reuse views between profiles. It's only useful if we're changing bits of them depending on the profile.
app/views/tablet/Main.js
Ext.define('MyApp.view.tablet.Main', {
extend: 'MyApp.view.Main',
initialize: function() {
this.add({
xtype : 'button',
action : 'coolBtn',
text : 'Running on a tablet'
});
this.callParent();
}
});
This looks great already. Just for the sake of extending I added additional button to the NavigationView. I'm going to set up a controller that will work with the button
app/controller/Main.js
Ext.define('MyApp.controller.Main', {
extend: 'Ext.app.Controller',
config: {
refs: {
coolButton: 'button[action=coolBtn]'
},
control: {
coolButton: {
tap: 'onCoolButtonTap'
}
},
routes: {
'show/:id' : 'showItem'
}
},
onCoolButtonTap: function(button) {
console.log(button === this.getCoolButton());
},
showItem: function(id) {
console.log('Showing item',id);
}
});
This is the awesome part, right here. Refs give us a quick access to components based on component query rules (button[action=coolBtn] means find my a xtype = button cmp that has property action = coolBtn). Refs add getter methods, too, as seen in onCoolButtonTap example.
Then I control the button and tell the app to monitor the tap event and assign a handler to it.
Another smart addition to the MVC pattern are routes. They will detect "commands" in your URI path, e.g. http://localhost/#show/7482 and execute them through the provided showItem handler.
Summary
I think that now you have the basic idea of how to start with your MVC app. With some curiosity you can expand the knowledge and create awesome apps.
Note that I've written this out of my head and haven't tested. Let me know if you find a typo or something.
Here are two videos from the sencha 2011 conference:
SenchaCon 2011: MVC in Depth Part 1
https://vimeo.com/33311074
and
SenchaCon 2011: MVC in Depth Part 2
https://vimeo.com/33430731
Also you can check their blog for other short tutorials.
Another video to better understand Sencha Touch 2
SenchaCon 2011: The Sencha Class System https://vimeo.com/33437222
Make sure you are using the Beta1 realease as it has the latest set of examples. If you take a look at the jog-with-friends example you can see how the class system works.
The first thing to understand is the application structure which consists of controllers, models, stores and views and how they are defined inside of Ext.Application...
They are still working on documentation and tutorials are scant, i learned the new class system from just looking at the sample app, take a look it will probably help to get you underway
Also the documentatikn for the class system is here: http://docs.sencha.com/touch/2-0/#!/guide/class_system
Edit: After posting this I saw that Beta2 is now released
Is there a script to make the browser refresh when a page is re-sized? More specifically, one that emulates the browser refresh button or F5? I've found two, but they don't quite do what I'm looking for;
<script type="text/javascript">
var currheight = document.documentElement.clientHeight;
window.onresize = function(){
if(currheight != document.documentElement.clientHeight) {
location.replace(location.href);
}
}
</script>
and
<body onResize="window.location=window.location;">
The problem with these two is they appear to completely reset the page where as using the browsers refresh function leaves some user made changes intact (like being at a specific hash for instance) which is what I need.
So is there a way to refresh the window on re-size with a script similar to if the browser refresh was clicked? I don't understand why there is even a difference but there is.
Thanks.
Yes, you probably want to take a look at some JavaScript events. There is an OnResize event.
Here's a link to get you started with events:
http://www.devarticles.com/c/a/JavaScript/OnReset-OnResize-and-Other-JavaScript-Events/
As far as reloading the page, you can do that too:
http://www.mediacollege.com/internet/javascript/page/reload.html
As far as keeping the user values, you could persist them in a session.
Here is the perfect solution :
I have included timeout of 1 sec i.e. browser will refresh after 1 sec of window resize
$(window).resize(function() {
setTimeout( function(){
window.location.href = window.location.href;
},1000);
});
Without timeout
$(window).resize(function() {
window.location.href = window.location.href;
});
NOTE : You may also use window.location.reload() instead of window.location.href = window.location.href
window.location.reload() reloads the current page with POST data, whilewindow.location.href=window.location.href does not include the POST data
-- hope it helps
Try this:
<![if !IE]> <body onresize="document.location=window.location;"> <![endif]>
<!--[if IE]> <body onresize="window.location.reload();"> <![endif]-->