Skip to main content
10-Marble
January 20, 2023
Solved

Invoke 3D Audio widget Service "Play"

  • January 20, 2023
  • 2 replies
  • 2325 views

Hello!

I have a problem with one of my new projects. I want to add audio which will be automatically played when I will click on a model with other stuff that will appear. But I don't know how can I invoke this function from 3D Audio widget. I always used this code to play animation in a model widget:

angular.element(document.getElementById('model-1')).scope().play();

I tried to change ('model-1')) to ('3DAudio-1')) but then Vuforia crash. Is there any different code to invoke this function from Home.js?

Best answer by RolandRaytchev

Hi @Pawel_D. 

I do not think that such object cast is possible,  so that a crash could occurs  on the  HL device
 What   do you want to do? Do you want to  play  an audio for each step of sequence or some thing like this. I have a sample  project where I am playing a model Sequence and for each sequence step it plays some audio file. I do not have access to my HL but it was working with some of the previous versions. so hopeful it will helpful for you.

 

 

//==================================
$scope.app.playAudio = function (mp3) {
 var audio = new Audio(mp3);
 audio.addEventListener('ended', function() {
 console.warn("mp3="+mp3+" finished!")
 console.warn("call the next audio from the list");
 }, false);
 
 audio.volume = 0.76;
 audio.play();
}; 
//
//==================================
$scope.$on('stepstarted', function(evt, arg1, arg2, arg3) { 
 var parsedArg3 = JSON.parse(arg3);
 

 
 
 console.log("stepName="+parsedArg3.stepName);
 console.log("stepDescription="+parsedArg3.stepDescription);
 console.log("nextStep="+parsedArg3.nextStep);
 
 $scope.stepDescription=parsedArg3.stepDescription;
 console.warn("Event: " + evt.name + " arg3 fields, name: " + parsedArg3.stepName + " duration(ms): " + parsedArg3.duration + " total steps: " + parsedArg3.totalSteps + " step desc: " + parsedArg3.stepDescription );
 
 $scope.app.playAudio('app/resources/Uploaded/seq_step_'+parsedArg3.stepNumber+'.mp3');
}); 

/////
$scope.$watch('view.wdg["model-1"].currentStep', function(val) {
 if(val !=undefined && val != "")
 $scope.setWidgetProp("3DLabel-3","text","app/resources/Uploaded/seq_step_"+val+".mp3")
});

$scope.playAudio = function(){
 let val=$scope.view.wdg["3DLabel-3"].text
 $scope.setWidgetProp("3DAudio-1","src",val)
$timeout(()=>{twx.app.fn.triggerWidgetService("3DAudio-1", 'play');},300)
}

 

 

where the play button is linked/bind to   app.view["Home"].wdg["model-1"].svc.play

 

 

 app.view["Home"].wdg["model-1"].svc.play
//is the same as you tried but on UI
angular.element(document.getElementById('model-1')).scope().play();

 

 

2 replies

24-Ruby III
January 20, 2023

 Hi,

 

Please specify which version of the program you are using.

Pawel_D.10-MarbleAuthor
10-Marble
January 20, 2023

Hello,

I am using Version 9.8.0 (9.8.0.5653).

21-Topaz I
January 20, 2023

Hi @Pawel_D. 

I do not think that such object cast is possible,  so that a crash could occurs  on the  HL device
 What   do you want to do? Do you want to  play  an audio for each step of sequence or some thing like this. I have a sample  project where I am playing a model Sequence and for each sequence step it plays some audio file. I do not have access to my HL but it was working with some of the previous versions. so hopeful it will helpful for you.

 

 

//==================================
$scope.app.playAudio = function (mp3) {
 var audio = new Audio(mp3);
 audio.addEventListener('ended', function() {
 console.warn("mp3="+mp3+" finished!")
 console.warn("call the next audio from the list");
 }, false);
 
 audio.volume = 0.76;
 audio.play();
}; 
//
//==================================
$scope.$on('stepstarted', function(evt, arg1, arg2, arg3) { 
 var parsedArg3 = JSON.parse(arg3);
 

 
 
 console.log("stepName="+parsedArg3.stepName);
 console.log("stepDescription="+parsedArg3.stepDescription);
 console.log("nextStep="+parsedArg3.nextStep);
 
 $scope.stepDescription=parsedArg3.stepDescription;
 console.warn("Event: " + evt.name + " arg3 fields, name: " + parsedArg3.stepName + " duration(ms): " + parsedArg3.duration + " total steps: " + parsedArg3.totalSteps + " step desc: " + parsedArg3.stepDescription );
 
 $scope.app.playAudio('app/resources/Uploaded/seq_step_'+parsedArg3.stepNumber+'.mp3');
}); 

/////
$scope.$watch('view.wdg["model-1"].currentStep', function(val) {
 if(val !=undefined && val != "")
 $scope.setWidgetProp("3DLabel-3","text","app/resources/Uploaded/seq_step_"+val+".mp3")
});

$scope.playAudio = function(){
 let val=$scope.view.wdg["3DLabel-3"].text
 $scope.setWidgetProp("3DAudio-1","src",val)
$timeout(()=>{twx.app.fn.triggerWidgetService("3DAudio-1", 'play');},300)
}

 

 

where the play button is linked/bind to   app.view["Home"].wdg["model-1"].svc.play

 

 

 app.view["Home"].wdg["model-1"].svc.play
//is the same as you tried but on UI
angular.element(document.getElementById('model-1')).scope().play();

 

 

Pawel_D.10-MarbleAuthor
10-Marble
January 23, 2023

Hi!

Thank you very much for your response. I am not very good in programming so I think that my code is very "primitive" 🙂 Maybe that is the case why my Experience shut down on Hololens?
I want to create a simple guide in our office, for a new employees. They will follow a model of a robot, that will stop on each doors and preview text + audio. I've created a robot animation and a route in Creo Illustrate, every step in Sequence is a different department in our office (so every step should view different text and audio). I've created a count function which will add +1 to s value with every click on a model:

Pawel_D_0-1674459742890.png

After that I have created a check function, which will check current s value and view audio file and text for every step with different time delay for a robot to get to the door:

Pawel_D_2-1674460400294.png

The last function is a play and hide text function, when person will click a robot model to go to the next door:

Pawel_D_3-1674460670788.png

All these functions are then set to "Click" event of model-1 widget:

Pawel_D_0-1674463235726.png

When I uploaded Experience and viewed it on a Hololens, everything goes fine until I click on a model to go to the second step - Experience "freezes" and Vuforia View shut down. I've tried it couple of times, with different options and it is the same case every time. 

21-Topaz I
January 23, 2023

Hi @Pawel_D. ,

one thing -  var s is global setting in Home.js but possibly not visible in the environment of the click button. So better to use

$scope.s  instead.

Another point is - try to call only one function in the JS UI. which will call all these code of the 3 routine. 

Then you have to pay attention that the call is called asynchronously and possibly the order of call occurs  in different order aa indented. E.g. in check you check variable s but it is possibly not initialized  yet or not changed as expected

I think it is more recommended to use the JS event . E.g. to start the code for step e.g. on in the step one beginning (stepstarted) or step finishing event as suggested in the small example . Another option is to watch the change of variable or property e.g. in example the property current step of the model widget.

Did you test the sample code from my previous post? Thanks