Is there a solution for Three to show subtitles?

Hi all
I am looking for a solution to show different subtitles. I have written something by hand in the following example, but I am not completely satisfied with it. It should be so that the different subtitles are loaded with the various clips. When you click Argument1 should Button1 Array1 Clip1.1 and also Text1.1 appear, and if Argument2 is pressed then Button2 Array1 Clip2.1 and alsoText2.1 should be loaded. See it on Console.
Fiddle

Actually, everything works, but that with the subtitles does not want yet. Does anyone have a solution for this problem ? Many Thanks !!

If you need subtitles for audio or video, you might want to have a look at the HTML5 Track Element.

The track element provides a simple, standardized way to add subtitles, captions, screen reader descriptions and chapters to video and audio.

@Mugen87 thanks for the answer. I see that Firefox is not supported :frowning: The animations are running in a Canvas, so they are not videos. So I think it should work with my code, in principle it already works. But I can’t load different Arrays with different subtitles. Maybe they have a solution for this problem?

Firefox does support the HTML5 track elements by this time. The article is just too old.

https://caniuse.com/#feat=webvtt

I’ve suggested this API because even if you have just audio files, you need to synch the audio with the subtitles. This is something where WebVTT could be really helpful.

@Mugen87 oh yes, looks good !! Thanks for the hint. I will test that.

@Mugen87 I looked at that and I assume that I have to install an audio player before it can work. But I only use the THREE.AudioLoader and the THREE.bvhLoader to play the data together. So I do not have a timeline for reference. Is that possible on this way ?

The problem is that THREE.AudioLoader returns decoded audio buffers for AudioBufferSourceNode objects. AFAIK, these WebAudio entities are not compatible with WebVTT. Instead you have to do something like this:

https://jsfiddle.net/f2Lommf5/835/

@Mugen87 that was exactly the problem, thank you!! That would have to work. I’m trying to put that into my example.

You’re welcome! :blush:

@Mugen87 I have one more question. I have the whole integrated, now the audio files loaded twice. 1. can the subtitles not be executed via audioLoader or clip1? They are already loaded on this way. The subtitles should therefore only be added. 2. for the other arguments different subtitle blocks should can be loaded. Do I not need an array for that? https://jsfiddle.net/f2Lommf5/843/ Next -> Argument1 or Argument2 -> Play
Thank You!!

I thought of something like that, but it is not working.

const audio = new Audio( audioUrl );	

const track1 = audio.addTextTrack( 'subtitles' );

const cue1 = new VTTCue( 1, 2, 'Text1.1' );  
const cue2 = new VTTCue( 2, 10, 'second text' );
const cue3 = new VTTCue( 10, 15, 'end' ); 

track1.addCue( cue1 );
track1.addCue( cue2 );
track1.addCue( cue3 );

cue1.onenter = cue2.onenter = cue3.onenter = onEnter1;


const track2 = audio.addTextTrack( 'subtitles' );

const cue4 = new VTTCue( 1, 2, 'Text2.1' );   
const cue5 = new VTTCue( 2, 10, 'second text' ); 
const cue6 = new VTTCue( 10, 15, 'end' );

track2.addCue( cue4 );
track2.addCue( cue5 );
track2.addCue( cue6 );

cue4.onenter = cue5.onenter = cue6.onenter = onEnter2;

if ( audioUrl = clip1 ) {
	function onEnter1( event ) {			
		console.log( 'Subline 1 is loadet' );		
		//document.getElementById( 'subtitles' ).innerHTML = event.target.text;		
	}
    }	

if ( audioUrl = clip2 ) {
	function onEnter2( event ) {			
		console.log( 'Subline 2 is loadet' );		
		//document.getElementById( 'subtitles' ).innerHTML = event.target.text;	
	}
    }	
}

Sry, i had not the time to look at your code in detail. But one thing is obvious: You have to do a audio.play() in order to trigger the onEnter() callbacks. The cues won’t appear if you not actually playback the audio.

The audio.play() is executed with the play-button. This can be seen in the fiddle. But thank you for the help so far.

        play.onclick = function playClip() {
	console.log( `\nplayClip()` );
	play.style.background = "#92ddb8";		
  
	reset.disabled = false;
	play.disabled = true;
	paused.disabled = false;

	sound.play();
	audio.play();     // <-----
}