Microsoft Azure Media Player Start At Defined Time - asp.net

I have just started familiarising the azure media player and need to achieve setting the video to a defined timeframe at load.The code I have used so far is as follows.The reference used in the application also as part of the question.
<link href="//amp.azure.net/libs/amp/latest/skins/amp-default/azuremediaplayer.min.css" rel="stylesheet">
<script src="//amp.azure.net/libs/amp/latest/azuremediaplayer.min.js"></script>
<script>
amp.options.flashSS.swf = "//amp.azure.net/libs/amp/latest/techs/StrobeMediaPlayback.2.0.swf"
amp.options.flashSS.plugin = "//amp.azure.net/libs/amp/latest/techs/MSAdaptiveStreamingPlugin-osmf2.0.swf"
amp.options.silverlightSS.xap = "//amp.azure.net/libs/amp/latest/techs/SmoothStreamingPlayer.xap"
</script>
#{
var ContentUrl = ViewBag.ContentUrl;
}
<video id="vd123" class="azuremediaplayer amp-default-skin amp-big-play-centered">
</video>
<script>
var myOptions = {
//"nativeControlsForTouch": false,
techOrder: ["azureHtml5JS", "flashSS", "silverlightSS", "html5"],
"nativeControlsForTouch": false,
autoplay: false,
controls: true,
width: "640",
height: "400",
poster: ""
};
var myPlayer = amp("vd123", myOptions, function () {
});
myPlayer.src([
{
src: "src",
type: "application/vnd.ms-sstr+xml"
},
]);
myPlayer.currentTime(5);
</script>
Set begin time of Azure Media Player looked at this URL but not provided full code or not feeling any difference to what I tried?

As mentioned in the linked thread there are two ways to achieve this depending on your specific scenario. If you want to start at a specific time because there is a preroll slate (or like content that you don't care for your user to see), you should use the dynamic manifests in Azure Media Services. This is the recommended method and is generally the main scenario.
Also, as mentioned in the linked thread, if you wish to have done specifically in the player (so that means the content is actually viewable but just want to start at a specific time), you should listen for the play or playing event and set the currentTime after that point.
A simple way to do this is directly after setting the source of Azure Media Player:
myPlayer.addEventListener(amp.eventName.play, startTime);
function startTime() {
myPlayer.currentTime(5);
myPlayer.removeEventListener(amp.eventName.play, startTime)
}

Related

Full Calendar - refetchResources

I am confused on how to refetch the resources by url (json feed).
This renders my calendar resources -
$('#calendar').fullCalendar({
...
resources: 'example.json?id=1',
...
});
This documentation (https://fullcalendar.io/docs/refetchResources) says "If the resources option was specified as a JSON feed it will be requested again."
So I have a button that I want to click to change the resource url and reload the resource feed -
$('.resource-button').on('click', function() {
link = $(this).attr('href');
$('#calendar').fullCalendar('refetchResources', {
resources: link
});
});
Any idea why it doesn't reload the new resource link? The list of resources refreshes like it is doing something but the data stays the same.
Thanks
This code
$('#calendar').fullCalendar('refetchResources', {
resources: link
});
makes no sense. As per the documentation you linked to, the "refetchResources" method does not accept any extra arguments. The { resources: link } object you supply to it is not expected, and is consequently ignored by fullCalendar. I'm not sure what gave you the idea that you could pass more arguments to this function.
The phrase you quoted:
"If the resources option was specified as a JSON feed it will be requested again."
means it will re-fetch existing resource data from the existing specified sources (hence the word "again"). I think you have misunderstood this explanation.
In other words all it does is refresh the already-specified sources. If you wish to change the list of resource dynamically, then you need to set the resources option first using the separate method to set options.
Here's an example which switches the resources from one URL to another when a button is clicked. You can of course adjust this to your needs, but the key thing to note is the use of the separate "option" method to change the Resource URL before calling "refetchResources".
HTML:
<button type="button" id="changeResources">
Click to Change Resources
</button>
<div id='calendar'></div>
JavaScript:
var resources = [
"https://api.myjson.com/bins/m7blz",
"https://api.myjson.com/bins/cqj3b"
]
var currentResourceIndex = 0;
$(document).ready(function() {
$('#calendar').fullCalendar({
resources: resources[currentResourceIndex],
schedulerLicenseKey: 'CC-Attribution-NonCommercial-NoDerivatives',
defaultView: 'timelineDay',
header : {
left: 'prev, today',
center: 'title',
right: 'next'
},
});
$("#changeResources").click(function() {
if (currentResourceIndex == 0) currentResourceIndex = 1;
else currentResourceIndex = 0;
$('#calendar').fullCalendar('option', 'resources', resources[currentResourceIndex]);
$("#calendar").fullCalendar("refetchResources");
});
});
See http://jsfiddle.net/toytd26b/57/ for a working demonstration of switching the resources using a button (as per the code above).
See https://fullcalendar.io/docs/dynamic-options for documentation of how to set calendar options after the calendar has been initialised.
$('.resource-button').on('click', function() {
link = $(this).attr('href');
$('#calendar').fullCalendar('option', 'resources', link);
$('#calendar').fullCalendar('refetchResources');
});

Add video in aframe dynamically

My requirement is to simply play a video (url in json file) on a plane in aframe. I have created video entity in my html as follows
<a-video id="video_1" position="0 0 2" geometry="width:2.4;height:1.4"></a-video>
Inside my register component i have added the src file to video as below
AFRAME.registerComponent('myComp', {
schema: {
file: {type: 'asset', default: 'assets/data/file1.json'},
var: {type: 'number', default: 0}
},
init: function () {
},
update: function () {
var data = this.data;
var scene = this.el.sceneEl;
var screen = scene.querySelector('#video_' + data.var);
load(data.file, function (response) {
var products = response.mydata;
screen.setAttribute('src',products[data.var].videoUrl);
});
this.el.addEventListener('mouseenter', function () {
console.log("mouseenter",screen.getAttribute('src'));
});
}
});
My console log is displayed with path mentioned in the json file
"mouseenter assets/img/movies/videos/video1.mp4"
In network tab, i could see my file got fetched with type media and status 200. But still i am getting error
components:texture:warn `$s` is not a valid video +41ms assets/img/movies/videos/video1.mp4
index.html:1 [.Offscreen-For-WebGL-000000BA313F15D0]RENDER WARNING: texture bound to texture unit 0 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering.
What is the correct way to add the video. Where am i going wrong. Please help
I was having the same problem and just managed to get it work in Chrome with something like this:
// Create a new asset
var new_asset = document.createElement('video');
new_asset.setAttribute('id', 'dynVid'); // Create a unique id for asset
new_asset.setAttribute('src', videoUrl);
// Append the new video to the a-assets, where a-assets id="assets-id"
document.getElementById('assets-id').appendChild(new_asset);
// Add the asset to the a-video
screen.setAttribute('src', '#dynVid');
// Start playback
new_asset.play();
This has the added benefit that you can control playback if necessary (new_asset.pause(), new_asset.currentTime = X, muted = true, etc).
For larger videos, you may need to add some callbacks, like oncanplaythrough, to wait until the video has loaded enough.
https://aframe.io/docs/0.5.0/guides/using-javascript-and-dom-apis.html#creating-an-entity-with-createelement
var videoEl = document.createElement('a-video');
videoEl.setAttribute('src', videoUrl);
this.el.appendChild(videoEl);

Loading Google Places Autocomplete Async Angular 2

I am trying to instantiate a Google Places Autocomplete input within an Angular 2 component. I use this code to do it:
loadGoogle() {
let autocomplete = new google.maps.places.Autocomplete((this.ref.nativeElement), { types: ['geocode'] });
let that = this
//add event listener to google autocomplete and capture address input
google.maps.event.addListener(autocomplete, 'place_changed', function() {
let place = autocomplete.getPlace();
that.place = place;
that.placesearch = jQuery('#pac-input').val();
});
autocomplete.addListener()
}
Normally, I believe, I would use the callback function provided by the Google API to ensure that it is loaded before this function runs, but I do not have access to it within a component's scope. I am able to load the autocomplete input 90% of the time, but on slower connections I sometimes error out with
google is not defined
Has anyone figured out how to ensure the Google API is loaded within a component before instantiating.
Not sure whether this will help, but I just use a simple script tag in my index.html to load Google API and I never get any error. I believe you do the same as well. I post my codes here, hope it helps.
Note: I use Webpack to load other scripts, except for Google Map API.
<html>
<head>
<base href="/">
<title>Let's Go Holiday</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Google Map -->
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=<your-key>&libraries=places"></script>
</head>
<body>
<my-app>Loading...</my-app>
</body>
</html>
And then in your component:
...
declare var google: any;
export class SearchBoxComponent implements OnInit {
ngOnInit() {
// Initialize the search box and autocomplete
let searchBox: any = document.getElementById('search-box');
let options = {
types: [
// return only geocoding results, rather than business results.
'geocode',
],
componentRestrictions: { country: 'my' }
};
var autocomplete = new google.maps.places.Autocomplete(searchBox, options);
// Add listener to the place changed event
autocomplete.addListener('place_changed', () => {
let place = autocomplete.getPlace();
let lat = place.geometry.location.lat();
let lng = place.geometry.location.lng();
let address = place.formatted_address;
this.placeChanged(lat, lng, address);
});
}
...
}
I used it the same way as explained above but as per google page speed i was getting this suggestion,
Remove render-blocking JavaScript:
http://maps.googleapis.com/…es=geometry,places&region=IN&language=en
So i changed my implementation,
<body>
<app-root></app-root>
<script src="http://maps.googleapis.com/maps/api/js?client=xxxxx2&libraries=geometry,places&region=IN&language=en" async></script>
</body>
/* Now in my component.ts */
triggerGoogleBasedFn(){
let _this = this;
let interval = setInterval(() => {
if(window['google']){
_this.getPlaces();
clearInterval(interval);
}
},300)
}
You can do one more thing, emit events once the value(google) is received,& trigger your google task
inside them.

jsdom does not fetch scripts on local file system

This is how i construct it:
var fs = require("fs");
var jsdom = require("jsdom");
var htmlSource = fs.readFileSync("./test.html", "utf8");
var doc = jsdom.jsdom(htmlSource, {
features: {
FetchExternalResources : ['script'],
ProcessExternalResources : ['script'],
MutationEvents : '2.0'
},
parsingMode: "auto",
created: function (error, window) {
console.log(window.b); // always undefined
}
});
jsdom.jQueryify(doc.defaultView, 'https://code.jquery.com/jquery-2.1.3.min.js', function() {
console.log( doc.defaultView.b ); // undefined with local jquery in html
});
the html:
<!DOCTYPE HTML>
<html>
<head></head>
<body>
<script src="./js/lib/vendor/jquery.js"></script>
<!-- <script src="http://code.jquery.com/jquery.js"></script> -->
<script type="text/javascript">
var a = $("body"); // script crashes here
var b = "b";
</script>
</body>
</html>
As soon as i replace the jquery path in the html with a http source it works. The local path is perfectly relative to the working dir of the shell / actual node script. To be honest i don't even know why i need jQueryify, but without it the window never has jQuery and even with it, it still needs the http source inside the html document.
You're not telling jsdom where the base of your website lies. It has no idea how to resolve the (relative) path you give it (and tries to resolve from the default about:blank, which just doesn't work). This also the reason why it works with an absolute (http) URL, it doesn't need to know where to resolve from since it's absolute.
You'll need to provide the url option in your initialization to give it the base url (which should look like file:///path/to/your/file).
jQuerify just inserts a script tag with the path you give it - when you get the reference in the html working, you don't need it.
I found out. I'll mark Sebmasters answer as accepted because it solved one of two problems. The other cause was that I didn't properly wait for the load event, thus the code beyond the external scripts wasn't parsed yet.
What i needed to do was after the jsdom() call add a load listener to doc.defaultView.
The reason it worked when using jQuerify was simply because it created enough of a timeout for the embedded script to load.
I had the same issue when full relative path of the jquery library to the jQueryify function. and I solved this problem by providing the full path instead.
const jsdom = require('node-jsdom')
const jqueryPath = __dirname + '/node_modules/jquery/dist/jquery.js'
window = jsdom.jsdom().parentWindow
jsdom.jQueryify(window, jqueryPath, function() {
window.$('body').append('<div class="testing">Hello World, It works')
console.log(window.$('.testing').text())
})

How can I tell if my Google content experiment is running?

I've created a google content experiment without redirects using the docs.
The basic implementation involves a javascript snippet that uses the following code to choose the version of the experiment:
<!-- Load the Content Experiment JavaScript API client for the experiment -->
<script src="//www.google-analytics.com/cx/api.js?experiment=YOUR_EXPERIMENT_ID"></script>
<script>
// Ask Google Analytics which variation to show the user.
var chosenVariation = cxApi.chooseVariation();
</script>
<!-- Load the JQuery library -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script>
// Define JavaScript for each page variation of this experiment.
var pageVariations = [
function() {}, // Original: Do nothing. This will render the default HTML.
function() { // Variation 1: Banner Image
document.getElementById('banner').src = 'bay-bridge.jpg';
},
function() { // Variation 2: Sub-heading Text
document.getElementById('heading').innerHTML = 'Look, a Bridge!';
},
function() { // Variation 3: Button Text
document.getElementById('button').innerHTML = 'Learn more';
},
function() { // Variation 4: Button Color
document.getElementById('button').className = 'button button-blue';
}
];
// Wait for the DOM to load, then execute the view for the chosen variation.
$(document).ready(
// Execute the chosen view
pageVariations[chosenVariation]
);
</script>
However, when I visit the page using an incognito window, I only see the first variation of the experiment. When I check chosenVariation in the console, it's always 0. In fact, when I call cxApi.chooseVariation(); in the console, it always returns 0.
Is this because google recognizes my incognito browser windows, or is something broken with cxApi.chooseVariation(); or in my implementation?
I had the same problem, 100% of the sessions were given the original (0) variation. In order to fix the problem, I added the javascript code provided by the experiment. Go to your experiment (edit), click Setting up your experiment code, manually insert the code, copy the code in there.
Now since you (and I) don't want to have a redirect, remove this part at the end of the code <script>utmx('url','A/B');</script>. If your page is templated, you can use a variable and insert your experiment key (not experiment id) where you see var k='########-#'
Now either very few people use the experiments in a client-only fashion or we're totally stupid because it would seem to me that the guide is wrong and there's absolutely no documentation that shows a working client-only setup.

Resources