In Metaio Creator - How would I prevent fullscreenVideo from auto playing? - javascript

I'm posting here because the Metaio forums are awful and nobody responds so I figured it can't hurt to try here. Metaio Creator is an augmented reality software program.
I don't want the fullscreen Video to go auto play but wait until I touch a 3D object to trigger that fullscreen function.
Half an answer I found said to export the Creator project and edit the logic.js file by removing "fullscreenVideo1.display();" from the trackable's "onDetected" function.
I'm wondering how to import that edited logic.js file back into my project.
Or better yet, how I could edit the custom arel script from within Metaio Creator's UI.
Here is a link to the half answer:
http://helpdesk.metaio.com/questions/19749/how-to-stop-auto-loading-of-fullscreen-video
Here is what the editable arel script looks like for all fullscreen Videos by default.
// Will be executed when the viewer for this object has been closed.
fullscreenVideo3.onClosed = function () {
};
// Will be executed when this object has been loaded.
// Corresponds to arel.Events.Object.ONREADY event.
fullscreenVideo3.onLoaded = function () {
};
fullscreenVideo3.onDisplayed = function () {
};

You can edit arel code from Creator, just right click on the object and edit the arel file or in the menu "extras" > "open arel editor"

Basically, you can change the video to be played using either Metaio Creator or changing the script as you said. If you change it using Metaio Creator, it will do all the work for you, so no changes need to be done.
In the object properties, in the behaviour tab there is an option to enable/disable playing the video on detection.
When the play box is checked, something like the next piece of code is added to the logic.js script by Metaio Creator.
pattern2.onDetected = function () {
arel.Debug.log(this.objectName + ".onDetected()");
fullscreenVideo2.display();
};
If it’s not checked, the code shown above is not added to the AREL package, so it won’t be played on detection.

Related

Infinite loop when overriding graphHandlerMouseUp on MxGraph using Angular

I have a difficult question to explain and I'm way out of my comfort zone as far as expertise in Javascript, TrueType, Angular and MxGraph are concerned... Hope to be able to explain.
I have an Angular component displaying and MxGraph. I was able to integrate MxGraph with Angular following this link (How to integrate mxGraph with Angular 4?). Even if I use Angular 7, the solution still works...
The graph is displayed correctly on the page and everything works fine, including my override of the function graphHandlerMouseUp, which I do with this code:
// Save the position of the mouse when releasing the button: used for
// detecting the target in a drag and drop
mx.graphHandlerMouseUp = mx.mxGraphHandler.prototype.mouseUp;
mx.mxGraphHandler.prototype.mouseUp = function( graph, evt ) {
currentdropX = evt.graphX;
currentdropY = evt.graphY;
mx.graphHandlerMouseUp.apply(this, arguments);
}
When I run this page for the first time, no problem happens.
Then through a button I call a page with another component (through routing). If from this page I go back to the first component (again through a routerlink) the page and the component with the MxGraph loads correctly, BUT when I use this function (i.e., release the mouse button).
It seems to me a recoursive problem, as when I put a console output like this:
// Save the position of the mouse when releasing the button: used for
// detecting the target in a drag and drop
mx.graphHandlerMouseUp = mx.mxGraphHandler.prototype.mouseUp;
mx.mxGraphHandler.prototype.mouseUp = function( graph, evt ) {
currentdropX = evt.graphX;
currentdropY = evt.graphY;
// INIFINTE LOOP HERE
console.log("Test");
mx.graphHandlerMouseUp.apply(this, arguments);
}
The "Test" is written a number of times which is continuously growing. Yet, if I understood, this was the correct way of overriding the function. Of course on the first load of the page, "Test" is displayed once. Passing to another component and then back on this it is displayed an "infinite" number of times (until I reach the: "ERROR RangeError: Maximum call stack size exceeded")...
I tried also to remove that override, and besides the obvious lack of the functionality, the very same problem happened to the function "mxDragSource", which is overridden with the same approach.
As I said: I'm not expert enough in javascript, truetype, MxGraph or Angular, so any hint, even if obvious, is very welcome!
Thanks!
The first time you run your code, you store mx library's mouseUp event in a variable and you assign a new function to mouseUp event in which you call the old mouseUpEvent.
The second time you run your code, you store your current mouseUp event (that you have modified) and you assign a function in which you call the old mouseUpEvent, which is the same you stored previously. There goes your recursion !
What you need to do is override the third-party function properly, so you don't execute your code twice.
How to do it ?
You can create a mixin and use this mixin in your componentB/ If you have no idea what is it and how to do it, please reproduce your problem in a stackblitz I'll be glad to help you to implement it.

Audio duration NaN on certain page request action

I have been trying to create my custom media player using HTML5 and Jquery.
I have followed different approaches and ran into some trouble based on my way of refreshing the page.
First Case
$(document).ready(function(){
duration = Math.ceil($('audio')[0].duration);
$('#duration').html(duration);
});
In this case, the duration returns NaN when I redirect the page to the same URL by pressing the ENTER key in the address bar. However, it works completely fine when I refresh using the reload button or by pressing the F5 button.
Second Case
I read in some answers that loading duration after the loadedmetadataevent might help. So I tried the following:
$(document).ready(function(){
$('audio').on('loadedmetadata', function(){
duration = Math.ceil($('audio')[0].duration);
$('#duration').html(duration);
});
});
Surprisingly, in this case, the inverse of the first case happened. The duration gets displayed completely fine in the case of a redirect, i.e., pressing ENTER while in the address bar. However, in the case of refreshing using the F5 button or the reload button, the duration doesn't get displayed at all, not even NaN which led me to believe that the code doesn't get executed at all.
Further reading suggested this might be a bug within the webkit browsers but I couldn't find anything conclusive or helpful.
What could be the cause behind this peculiar behavior?
It'd be great if you could explain it along with the solution to this problem.
Edit:
I am mainly looking for an explanation behind this difference in behavior. I would like to understand the mechanism behind rendering a page in the case of redirect and refresh.
It sounds like the problem is that the event handler is set too late, i.e. the audio file has loaded its metadata before the document is even ready.
Try setting the event handler as soon as possible by removing the $(document).ready call:
$('audio').on('loadedmetadata', function(){
duration = Math.ceil($('audio')[0].duration);
$('#duration').html(duration);
});
Note that this requires that the <script> tag be after the <audio> tag in the document.
Alternatively, you can tweak your logic slightly, so that the code that updates the duration always runs (but fails gracefully if it gets a NaN):
function updateDuration() {
var duration = Math.ceil($('audio')[0].duration);
if (duration)
$('#duration').html(duration);
}
$(document).ready(function(){
$('audio').on('loadedmetadata', updateDuration);
updateDuration();
});
Lovely code examples and stuff from people - but the explanation is actually very simple.
If the file is already in the cache then the loadedmetadata event will not fire (nor will a number of other events - basically because they've already fired by the time you attach your listeners) and the duration will be set. If it's not in the cache then the duration will be NaN, and the event will fire.
The solution is sort of simple.
function runWhenLoaded() { /* read duration etc, this = audio element */ }
if (!audio.readyState) { // or $audio[0].readyState
audio.addEventListener("loadedmetadata", runWhenLoaded);
// or $audio.on("loadedmetadata", runWhenLoaded);
} else {
runWhenLoaded.call(audio);
// or runWhenLoaded.call($audio[0]);
}
I've included the jQuery alternatives in the code comments.
According to w3 spec this is standard behavior when duration returns NaN.
So I suggest use durationchange event:
$('audio').on('durationchange', function(){
var duration = $('audio')[0].duration;
if(!isNaN(duration)) {
$('#duration').html(Math.ceil(duration));
}
});
NOTE: This code (and your too) will not work correct in case if you have more than one audio element on page. Reason is that you listen events from all audio elements on page and each element will fire own event:
$('audio').on('durationchange', function(){...});
OR
You can try:
<script>
function durationchange() {
var duration = $('audio')[0].duration;
if(!isNaN(duration)) {
$('#duration').html(Math.ceil(duration));
}
}
</script>
<audio ondurationchange="durationchange()">
<source src="test.mp3" type="audio/mpeg">
</audio>
Note that behaviors will differ from one browser to another. On Chrome, you have different type of loading. When resources are not in cache, it will fetch either the complete file (for js or css for example), either a part of the file (mp3 for example). This partial file contains metadata that allows browser to determine duration and other data such as the time it'll take to download whole file at this rate, trigerring for example canplay or canplaythrough events. If you look at network usage in you dev console, you'll see that the HTTP status code will be either 200 (succesful load) or 206(partial load - for mp3 for example).
When you hit refresh, elements are checked to see if they changed. HTTP status will then be 304, meaning file hasn't been modified. If it hasn't changed and is still in browser cache, then it won't be downloaded. The call to determine if it has or not changed comes from the server providing the file.
When ou simply click enter in adress bar, it's automatically taken from cache, not validating online. So it's much faster.
So depending on how you call or refresh your page (either simmple enter, refresh or complete refresh without cache), you'll have big differences on the moment you get the metadata from your mp3. Between taking the metadata from cache directly vs making a request to a server, the difference can be a few hundreds milliseconds, which is enough to change what data is available at different moment.
That being said, listening to loadedmetada should give consistent result. This event is triggered when the data with duration information is loaded, so whatever way the page is loaded, it shouldn't matter if that called is properly made. At this point you have to consider maybe some interference from other elements. What you should do is follow your audio through various events to get exactly where its at at different moments. So in you document ready you could add listeners for different event and see where the problem occurs. Like this:
$('audio')[0].addEventListener('loadstart', check_event)
$('audio')[0].addEventListener('loadeddata', check_event)
$('audio')[0].addEventListener('loadedmetadata', check_event)//at this point you should be able to call duration
$('audio')[0].addEventListener('canplay', check_event) //and so on
function check_event(e) {
console.log(e.target, e.type)
}
You'll see that depending on the way you refresh, these events can come at different moments, maybe explaining inconsistencies in your outputs.

Input type file triggering twice in mozilla(windows)

I have a strange issue with my website(using backbone.js,but i don't feel its something related to this framework). The template i am using is a bootstrap powered Admin theme called Ace Admin.
The HTML for file is as follows :
<input type="file" class="profileImage" name="profileImage" id="id-input-file-1" />
The Script associated for the same :
$('#id-input-file-1').ace_file_input({
no_file:'Image resolution 640*640',
btn_choose:'Choose',
btn_change:'Change',
droppable:false,
onchange:null,
thumbnail:true,
whitelist:'gif|png|jpg|jpeg',
blacklist:'exe|php',
//onchange:''
//
});
In mozilla alone, that too in windows machine, when i click on the input the file selection screen appears twice. To be precise, when i click the input the local drive window opens up. I select a file and close it. As soon as i close it another window opens up. In effect i have to close two windows one after another if i click on file input.
So my question is :
What am i doing wrong here?
Can i handle this in someway? Like say i get the click event and register the status and handle the second call by checking with status or so?
Is there a more obvious way of handling this through scripting?
My Input file :
The pop-up :
After 1 long month, i found the solution. There was a min file with the template and inside that there was a code as follows specially for mozilla :
if (b.browser.mozilla) {
n.on("click", function () {
if (!k.disabled && !m.attr("readonly")) {
m.click()
}
})
}
When i removed this, it no longer triggers the file upload twice. I guess this was used for older versions of mozilla. There was lots of styles related to a single file button and the original file type was hidden from view.

Include Javascript made from plugin into html button

We have a plugin that generates a JavaScript file. We want to run/execute this js file from within a html button, e.g.:
<input type=button value="Open js" onclick="javascript:window.open('http://jira.bltelecoms.net:8080/s/en_UScyxsyn/664/8/1.0.23-beta/_/download/batch/com.atlassian.jira.collector.plugin.jira-issue-collector-plugin:issuecollector/com.atlassian.jira.collector.plugin.jira-issue-collector-plugin:issuecollector.js?collectorId=e125274b','_self')" />
We use an third party web application called Jira and Confluence, part of the Atlassian suite. It's issue tracking software and it uses a plugin to create this JavaScript file which pops up a window, similar to a lightbox, in which you can fill in data and send it. By default it makes a trigger on the side of the page, how ever we want to execute this from a standard html button. Is there a way do do this?
You could make a new page which includes the script and open this page on click.
Or how about this:
function loadScript() {
var s = document.createElement('script');
s.src = "http://jira.bltelecoms.net:8080/s/en_UScyxsyn/664/8/1.0.23-beta/_/download/batch/com.atlassian.jira.collector.plugin.jira-issue-collector-plugin:issuecollector/com.atlassian.jira.collector.plugin.jira-issue-collector-plugin:issuecollector.js?collectorId=e125274b";
document.body.appendChild(s);
}
onclick="loadScript();"
I know that this is an old topic, but please see the following link:
https://confluence.atlassian.com/display/JIRA/Advanced+Use+of+the+JIRA+Issue+Collector#AdvancedUseoftheJIRAIssueCollector-Addingthecustomtriggerfunctionmanually
This shows how to set custom triggers for JIRA issue collectors. You will need a function to extend the global object ATL_JQ_PAGE_PROPS like below (jquery must be available).
window.ATL_JQ_PAGE_PROPS = $.extend(window.ATL_JQ_PAGE_PROPS, {
// ==== custom trigger function ====
triggerFunction : function( showCollectorDialog ) {
$('#feedback-button').on( 'click', function(e) {
e.preventDefault();
showCollectorDialog();
});
// add any other custom triggers for the issue collector here
}
});
So clicking on a DOM element with id="feedback-button" (or whatever other id you want to give it) will trigger your issue collector script.
Bear in mind the issue collector will need to specify a "Custom" trigger. You can do this by editing it in JIRA.
Hope this helps

Flash Microphone Event Resize

I have been recently studying and learning Flash AC3 and my intention was to make a small voice recorder for my website. I have been using google and the search engines and get different answers here and there but still it is not exactly working properly.
The problem I am having is, the flash plugin is 215x50 pixels. I know that unless it is 215x138 pixels, the flash player security panel will automatically NOT open.
I devised a work around which is that if and when the security is being called to open, I would resize the DIV the flash object is in using a javascript function called ResizeFlash to a size of 215x138 and then back again to 215x50 after the user makes a choice whether or not they allow the microphone.
Now I have been scratching my head for a few days because I DO get the following code to work and it does resize the DIV, but it does not resize the DIV back. I think I might have the call to ResizeFlash in the wrong place (???). I am not familiar enough to know where it might be wrong.
I keep rearranging the code to see if that would work and I would get times where it does resize to 215x138, open the Security Panel, then resize back to 215x50 but then the recording would not begin, as if I were stuck somewhere in a loop.
I hope that someone can please take some time and just take a glance at this code and show me the right way to handle this. Thank you very much!
Here is the code:
public function Main():void
{
recButton.stop();
submitButton.enabled = false; // These reset everything, maybe in wrong place??
activity.stop();
addListeners();
mic = Microphone.getMicrophone();
if (mic == null)
{
// no camera is installed
}
else if (mic.muted)
{
// user has disabled the access in security settings
mic.addEventListener(StatusEvent.STATUS, onMicStatus, false, 0, true); // listen out for their new decision
Security.showSettings('2'); // show security settings window to allow them to change security settings
}
else
{
// you have access
mic.setUseEchoSuppression(true); //... also this might be in wrong place?
// .. I would like this to always be on
}
}
private function addListeners():void
{
recButton.addEventListener(MouseEvent.MOUSE_UP, startRecording);
submitButton.addEventListener(MouseEvent.MOUSE_UP, onSend);
recorder.addEventListener(RecordingEvent.RECORDING, recording);
recorder.addEventListener(Event.COMPLETE, recordComplete);
activity.addEventListener(Event.ENTER_FRAME, updateMeter);
}
function onMicStatus(event:StatusEvent):void
{
if (event.code == "Microphone.Unmuted")
{
mic.removeEventListener(StatusEvent.STATUS, onMicStatus);
ExternalInterface.call('ResizeFlash', '215', '50'); // When the user presses allow, resize the div back to 215x50
}
}
private function startRecording(e:MouseEvent):void
{
recorder.record();
e.target.gotoAndStop(2);
recButton.removeEventListener(MouseEvent.MOUSE_UP, startRecording);
recButton.addEventListener(MouseEvent.MOUSE_UP, stopRecording);
}
private function stopRecording(e:MouseEvent):void
{
recorder.stop();
e.target.gotoAndStop(1);
recButton.removeEventListener(MouseEvent.MOUSE_UP, stopRecording);
recButton.addEventListener(MouseEvent.MOUSE_UP, startRecording);
}
I know that I have something in there in the wrong order..! I appreciate any comments.
Resizing the app back to 215x50 in the Microphone's status event handler may be too soon, as you have suggested.
Just a hunch, but that status event is dispatched immediately when the user clicks the "Allow" radio button in the Flash security panel. The panel is still open. In fact, if you leave it open and click between allow/deny it will get dispatched each time...
When the security panel is up, there are some things you cannot do. I wonder if using ExternalInterface (to resize the app) is falling into this bucket.
I would suggest the following:
Test your resize functionality without the security panel in the mix. Make sure this code successfully resizes the app in both directions.
Then have a look at this question about how to detect when the user actually closes the security panel. There are two approaches there, one is very hacky (the BitmapData.draw() hack) but I know it works. I suggest trying the second one, and commenting/upvoting there if it does work (I will too). It's a more elegant way to detect when the user closes the dialog, but I haven't had a chance to try it.
When you detect the dialog is closed, resize the app.

Categories

Resources