How to play BVH and audio together?

animation
audio

#1

Actually, this should go with the following example, but it does not. It all works as long as I use the direct path to audio. if I replace the path with URL in the audio, then no more audio is running.Does anyone see the mistake? Thanks!

<button id="BVHclip1">BVH_1</button>
<button id="BVHclip2">BVH_2</button>	



var audio1 = document.querySelector('#BVHclip1');
audio1.addEventListener('click', function () {
loadURL("three/models/Audio/Audio000.mp3");	
});

var audio2 = document.querySelector('#BVHclip2');
audio2.addEventListener('click', function () {
loadURL("three/models/Audio/Audio002.mp3");
});
////////////////////////////////////////////////
var clip1 = document.querySelector('#BVHclip1');
clip1.addEventListener('click', function () {
loadURL("three/models/BVH/Clip000.bvh");	
});

var clip2 = document.querySelector('#BVHclip2');
clip2.addEventListener('click', function () {
loadURL("three/models/BVH/Clip002.bvh");
});

	
//BVH loader	
var loadURL = function (url) {	

var loader = new THREE.BVHLoader();			
    loader.load( url, function( result ) {		
			
var boneContainer = new THREE.Group();
    boneContainer.add( result.skeleton.bones[ 0 ] );			
	
   scene.add( boneContainer );		

 //Audio loader
var listener = new THREE.AudioListener();		

var sound = new THREE.Audio( listener );		

var audioLoader = new THREE.AudioLoader();		
  //audioLoader.load( url, function( buffer ) {                                               //<-does not work.
    audioLoader.load( 'three/models/Audio/Audio000.mp3', function( buffer ) {  //<-that works.
    sound.setBuffer( buffer );
    sound.setLoop( false );
    sound.setVolume( 20 );
    sound.play();
});

mixer = new THREE.AnimationMixer( helper1 );				
	mixer.clipAction( result.clip ).setEffectiveWeight( 1.0 );		
	var action = mixer.clipAction( result.clip ).play();		
	action.setLoop( THREE.LoopOnce )

#2

Your code is not formatted well, so it’s hard to understand what’s actually going on. As far as i can see, the function loadURL() is used for loading BVH and audio assets. I think you should divide this work into separate functions. In this way, you avoid to trigger multiple requests for the same URL with different loaders.


#3

Thank you for the answer, I will try to clarify it with an better example.


#4

I made a fiddle, the problem should be obvious. Fiddle If the soundlink is selected directly in the audioLoader, it will work. but url does not work.


#5

There are a couple of issues with your code.

Firstly, the instance of AudioListener should be added to something, for example the camera. If you don’t do this, there is no way for the Panner to have knowlege about the position of the listener.

See docs: https://threejs.org/docs/#api/audio/AudioListener

The same applies to PositionalAudio. This should also be added to something in your scene. Again, see docs: https://threejs.org/docs/#api/audio/PositionalAudio

Secondly, the listener should only be added once and be attached to your camera. Think of them like your ears and the camera being your eyes. They are attached to the same object - your head. In this case, you only need to add the listener to the camera.

Third, and the most important: Why are you loading mp3 files using a BVHLoader?

Your code (redacted):

var loadURL = function (url) {

    var loader = new THREE.BVHLoader();
    loader.load( url, function( result ) {
        // mp3 url will never reach this code because .load fails.

        // A few lines later:
        audioLoader.load( url, function( buffer ) {
            // ... BVH files will never reach this part because .load fails.
        });
    });
}

So you’re basically running the same resource URL through loaders for 2 completely different file formats. That’ll never work,


#6

I refactored your code a little bit. This will avoid the problems mentioned by @Harold

https://jsfiddle.net/63a2p14p/2/

BTW: There is no need to create new loaders for each loading process. Always create your loader once and then reuse them.


#7

Now all you need is one AnimationMixer, same as what @Mugen87 said about the loaders :wink:


#8

@Harold Thanks for the explanations, now I can understand that and see the mistakes. Sometimes I have a board in front of my head :roll_eyes:


#9

No worries, happens to the best :slight_smile:


#10

@Mugen87 Thank you very much for the adjustments, that is very helpful. Stop and resume button should I can make self. It is ultimately about the animation with synchrony voice thats running with a click. Maybe it need a time of waiting to until everything is loaded, before can both playing .


#11

In this example, I have combined BVH and Sound to load it first, before it plays . However, the thing still makes “small” problems. What can I do to improve that? Thanks! https://jsfiddle.net/e3b9xhu2/3/


#12

What do you mean with “small” problems? :wink:


#13

The stopbutton does not always work and the skeletons are overlaid when the second animation is loadet and started. [ SOLVED ]