AudioVideoLib

K.V.

Here's the link to the library and the documentation:

http://textadventures.co.uk/games/view/phvys9dicuimsspr_m9wyq/audiovideolib


K.V.

When you click on 'Add script', you will see a few new options, one of which will say 'Add audio (NEW)'.

image


This will bring up this screen, where you can select a sound from your computer, just like the old play sound.

image


You have a few options here.

  • You can choose to show the audio controls, allowing the player to control things.

image


  • You can add an ID to the audio element, which allows you to control that individual sound thereafter.

image


  • You can add backup sources for browser compatibility, and you can enter URLs, as well.

image


  • You can add a script to run once the sound has finished. This was designed to be used with the sync option, but you can use it without syncing, too.

image


IMPORTANT NOTE:

Using the sync option does NOT actually interrupt play. It only keeps the player from entering commands until the sound has finished, but we can add a script to run once the sound has finished to accomplish our needs.

Here is an example where a sound "interrupts play" in between rooms:

image


Stopping sounds

You can stop all sounds with DestroyAllAudio. (This even stops sounds played with the old play sound script command.)


You can stop one sound with DestroyAudio(id), but you must know the ID. (An ID can be assigned when adding audio.)

image


CONCERNING THE MP3 FORMAT

The mp3 format will not work in the desktop player when using these functions. It will, however, play an ogg file. To exacerbate things, I am not sure if the Safari browser will play the ogg format. My solution is to include both formats, as seen in the above example.

To make sure your sound will work in the desktop player, either include an ogg along with an mp3, or use the old play sound script command.


Adding a video is exactly the same as adding a sound, except there is an extra parameter (or option) to use autoplay.

Just like the mp3 format, the desktop version of Quest will not play the mp4 format. (I use ogv as a backup source.)

image


image


Stopping videos

This works just like stopping audio. You can use DestroyAllVideo or DestroyVideo(id).

image


You can add backup sources for browser compatibility

However, the backup sources do not have to be on an external server (as in the example)?

And the good thing about this solution is that you can play several music pieces/sounds at the same time.

Would you give us additional functions to stop and resume the music? That would be very nice : -)


K.V.

However, the backup sources do not have to be on an external server

Correct!


the good thing about this solution is that you can play several music pieces/sounds at the same time.

Definitely!


additional functions to stop and resume the music

They are already in there, I just didn't add them to the GUI yet.


I just added video functions to the library, as well.

Here's a link to a list of all the functions:

http://media.textadventures.co.uk/games/PHVys9dICUiMSSpr_m9WYQ/documentation.html


great!


This is truly amazing... being able to add an ambient sound with no effort at all, and not having it conflict with the sound effects is incredible, and I feel it can add a lot to the ambience in certain types of videogames.
Furthermore, it's compatible with the old play sound function, so I could add it to my game on the fly. Truly a life saver.
Only one question, though... any details I should know as to how you should be credited, or how am I allowed to use it? I'd hate to piss someone off due to my own ignorance.


K.V.

Thanks! I'm glad you like it!

No credits are necessary, either. Feel free to do whatever you like with it!


Like


Pure awesomeness!


This is exactly what I'm looking for at the moment and... obviously I'd already found it and forgotten all about it.

One question: does it work to not upload anything and use the "backup" source only? If you understand what I mean?


K.V.

CONCERNING THE MP3 FORMAT

The mp3 and mp4 formats will not work in the desktop player when using these functions. It will, however, play an ogg or ogv file. To exacerbate things, I don't think the Safari browser will play the ogg and ogv formats. My solution is to include both formats, as seen in the above example.


Yeah; I got that :)
The one thing I'm still unsure of is if the user have to bundle the sound into the game or is it possible to ONLY use external (linked) files (no matter what the file extension)?


K.V.

The one thing I'm still unsure of is if the user have to bundle the sound into the game or is it possible to ONLY use external (linked) files (no matter what the file extension)?

If you have the sound hosted on an external site and you only link to that from within your game, there is no need to include the audio file in your game.

So, if your source is like https://whatever.com/mysound.mp3, you do not need to add the file to your game folder.

But, if your source is loading a local file, like GetFileURL("mysound.mp3"), you DO need to add the file to your game folder.


This applies to all file extensions and all file types.

If you are accessing a local file during play, that file must be in your main game's folder AND you must be sure the extension is included in game.publishfileextensions.


K.V.

Just to have the code in more than one place, here's the most recent AudioVideoLib.aslx file, which should work with v550 or v580 games.

<library>

  <!--
    This library has been modified to work with Quest 5.8.
    
    The documentation can be found here:
	http://textadventures.co.uk/games/view/phvys9dicuimsspr_m9wyq/audiovideolib

-->

  <function name="PlaySound" parameters="src, sync, loop, id, controls, addscript, callback">
    firsttime {
     SendToJsEval(play_audio_lib_stuff.js)
    }
    if (sync and loop) {
      error ("Attempted to loop and sync the same sound!")
    }
    src = GetSrc(src)
    if (id = "") {
      id = CreateAudioID()
    }
    id = Replace(id, " ", "_")
    JS.makeAudio (src, sync, loop, id, controls)
    if (addscript) {
      SetAudioCallback (id, callback)
    }
    if (sync) {
      DoAudioSync
    }
  </function>

  <function name="CreateAudioID" type="string">
    if (not HasAttribute(game,"audiofilesplayed")) {
    game.audiofilesplayed = 0
    }
    game.audiofilesplayed = game.audiofilesplayed + 1
    return ("audio-" + game.audiofilesplayed)
  </function>

  <function name="SetAudioCallback" parameters="id, callback">
    js = "$('#"+id+"').on('ended', function(){ASLEvent('EndAudioSyncAndInvoke',$(this).attr('id'));$(this).remove();});"
    JS.eval (js)
    if (not HasAttribute(game, "audiofinishedcallback")) {
    game.audiofinishedcallback = NewScriptDictionary()
    }
    dictionary add (game.audiofinishedcallback, id, callback)
  </function>

  <function name="DestroyAudio" parameters="id">
    JS.eval ("$('#"+id+"').remove();")
  </function>

  <function name="DestroyAllAudio">
    stop sound
    JS.eval ("$('audio').remove();")
    EndAudioSync("")
    game.audiofinishedcallback = NewScriptDictionary()
  </function>

  <function name="DestroyAudioAndRunScript" parameters="id">
    JS.eval ("$('#"+id+"').remove();")
    EndAudioSyncAndInvoke(id)
  </function>

  <function name="DoAudioSync">
    firsttime {
      JS.eval ("var sendCommandBak = sendCommand;")
    }
    game.audiosyncing = true
    JS.eval ("sendCommand = function(){$('input#txtCommand').val();};")
  </function>

  <function name="EndAudioSync" parameters="bs">
    game.preventturnscripts = true
    game.audiosyncing = false
    JS.endAudioSync()
  </function>

  <function name="EndAudioSyncAndInvoke" parameters="id">
    game.preventturnscripts = true
    game.audiosyncing = false
    JS.endAudioSync()
    if (HasAttribute(game, "audiofinishedcallback")) {
    if (DictionaryContains(game.audiofinishedcallback,id)) {
    invoke (ScriptDictionaryItem(game.audiofinishedcallback,id))
    dictionary remove(game.audiofinishedcallback,id)
    if (DictionaryCount(game.audiofinishedcallback)>0){
    DoAudioSync
    }
    }
    }
  </function>

  <function name="GetSrc" parameters="src" type="string">
    src = Split(src,";")
    online = false
    pres = Split("http;ftp",";")
    tags = NewStringList()
    foreach (url, src) {
    foreach (pre, pres) {
    if (StartsWith(url,pre)) {
    online = true
    }
    }
    arr = Split(url,".")
    type = arr[ListCount(arr)-1]
    if (online) {
    thisurl = url
    }
    else {
    thisurl = (GetFileURL(url))
    }
    list add (tags, Chr(60)+"source src=\""+thisurl+"\" type=\"audio/"+type+"\" "+Chr(62))
    }
    srctags = Join(tags,"")
    srctags = Replace(srctags,"/ogv","/ogg")
    return (srctags)
  </function>

  <!--
    FinishTurn modified function to keep turn scripts from firing when ending a sync
-->
  
   <function name="FinishTurn">
      <![CDATA[
    // Modded by KV to handle multiple commands, v550, and v580 correctly
    if (HasAttribute (game, "runturnscripts") or GetAttribute(game, "aslversion") = "580" or GetBoolean(game, "multiplecommands")){
      if (not GetBoolean(game, "suppressturnscripts")) {
        if (GetBoolean (game, "runturnscripts")){
          RunTurnScripts
        }
      }
	    game.runturnscripts = false
    }
	  else if (not GetBoolean(game, "suppressturnscripts")) {
      if (GetBoolean (game, "feature_turncount")){
        IncreaseObjectCounter(game, "turncount")
      }
      RunTurnScripts
    }
    // END OF MOD
    game.suppressturnscripts = false
    UpdateStatusAttributes
    CheckDarkness
    UpdateObjectLinks
  ]]></function>
  
  
  -->

  <!-- EXTRAS  -->


  <!-- 
    The following functions are technically unnecessary, but I think they are nice to have.
-->

  <function name="PlayAudio" parameters="src">
    PlaySound (src, false, false, "", false, false) {
    }
  </function>

  <function name="PlayAudioID" parameters="src, id">
    PlaySound (src, false, false, id, false, false) {
    }
  </function>

  <function name="PlayAudioLooped" parameters="src">
    PlaySound (src, false, true, "", false, false) {
    }
  </function>

  <function name="PlayAudioLoopedID" parameters="src, id">
    PlaySound (src, false, true, id, false, false) {
    }
  </function>

  <function name="PlayAudioSynced" parameters="src">
    PlaySound (src, true, false, "", false, false) {
    }
  </function>

  <function name="PlayAudioSyncedID" parameters="src, id">
    PlaySound (src, true, false, id, false, false) {
    }
  </function>

  <function name="PlayAudioSyncedWithCallback" parameters="src, callback">
    PlaySound (src, true, false, "", false, true, callback)
  </function>

  <function name="PlayAudioSyncedIDWithCallback" parameters="src, id, callback">
    PlaySound (src, true, false, id, false, true, callback)
  </function>

  <function name="PlayAudioControls" parameters="src">
    PlaySound (src, false, false, "", true, false) {
    }
  </function>

  <function name="PlayAudioIDControls" parameters="src, id">
    PlaySound (src, false, false, id, true, false) {
    }
  </function>

  <function name="PlayAudioLoopedControls" parameters="src">
    PlaySound (src, false, true, "", true, false) {
    }
  </function>

  <function name="PlayAudioLoopedIDControls" parameters="src, id">
    PlaySound (src, false, true, id, true, false) {
    }
  </function>

  <function name="PlayAudioSyncedControls" parameters="src">
    PlaySound (src, true, false, "", true, false) {
    }
  </function>

  <function name="PlayAudioSyncedIDControls" parameters="src, id">
    PlaySound (src, true, false, id, true, false) {
    }
  </function>

  <function name="PlayAudioSyncedWithCallbackControls" parameters="src, callback">
    PlaySound (src, true, false, "", true, true, callback)
  </function>

  <function name="PlayAudioSyncedIDWithCallbackControls" parameters="src, id, callback">
    PlaySound (src, true, false, id, true, true, callback)
  </function>

  <function name="PauseAudio" parameters="id">
    JS.pauseAudio(id)
  </function>

  <function name="ResumePausedAudio" parameters="id">
    JS.resumePausedAudio(id)
  </function>

  <function name="SetAudioVolume" parameters="id,vol">
    // vol must be between 0 and 1
    JS.setAudioVolume(id,vol)
  </function>

  <function name="MuteAudio" parameters="id">
    JS.muteAudio(id)
  </function>

  <function name="UnmuteAudio" parameters="id">
    JS.unmuteAudio(id)
  </function>

  <function name="MuteAllAudio">
    JS.muteAllAudio()
  </function>

  <function name="UnmuteAllAudio">
    JS.unmuteAllAudio()
  </function>

  <function name="PauseAllAudio">
    JS.pauseAllAudio()
  </function>

  <function name="RestartAllPausedAudio">
    JS.restartAllPausedAudio()
  </function>

  <function name="SetAllAudioVolume" parameters="vol">
    // vol must be between 0 and 1
    JS.setAllAudioVolume(vol)
  </function>

  <function name="SetAudioPosition" parameters="id,pos">
    JS.setAudioPosition(id,pos)
  </function>

  <function name="IncreaseVolume" parameters="id">
    <![CDATA[
    // vol must be between 0 and 1 
    JS.increaseVolume(id)
  ]]>
  </function>

  <function name="DecreaseVolume" parameters="id">
    <![CDATA[
    // vol must be between 0 and 1 
    JS.decreaseVolume(id)
  ]]>
  </function>

  <function name="IncreaseAllVolume" parameters="id">
    JS.increaseAllVolume()
  </function>

  <function name="DecreaseAllVolume" parameters="id">
    JS.decreaseAllVolume()
  </function>

  <!-- END OF UNNECESSARY FUNCTIONS -->



  <!-- 
    DEBUGGING FUNCTIONS 
-->

  <!--
    AudioLog and TestAudio are not used by any functions.
    They are only included for debugging purposes.
-->

  <function name="AudioLog" parameters="text">
    game.preventturnscripts = true
    Log (text)
  </function>
  <function name="TestAudio" parameters="src">
    s = Chr(60)+"audio src='"+GetSrc(src)+"' '"
    JS.testAudio (s)
  </function>




  <!-- Javascript stuff -->

  <function name="SendToJsEval" parameters="data">
    <![CDATA[
    regEx = "//"
	js = Split(data,Chr(60)+"br/"+Chr(62))
	notes = NewStringList()
	foreach (line, js) {
	  if (StartsWith(line,"//")) {
		list add (notes, line)
	  }
	}
	js = ListExclude(js,notes)
	finaljs = NewStringList()
	foreach (line, js) {
	  code = line
	  if (IsRegExMatch(regEx,line)) {
		list = Split(line,"//")
		code = list[0]
	  }
	  list add (finaljs, code)
	}
	js = Join(finaljs,"")
	js = Replace(js, "[br]", Chr(60)+"br/"+Chr(62))
	js = Replace(js, "[br/]", Chr(60)+"br/"+Chr(62))
	js = Replace(js, "[break]", Chr(60)+"br/"+Chr(62))
	js = Replace(js, "[linebreak]", Chr(60)+"br/"+Chr(62))
	JS.eval (js)
  ]]>
  </function>

  <command name="play_audio_lib_stuff">
    <parent>game</parent>
    <js>
      <![CDATA[
function isMobilePlayer(){if (typeof(currentTab) === 'string'){return true;}return false;};

function makeAudio(src,sync,loop,id,controls,callback){
  if (sync && loop){
    throw new Error('makeAudio():  Attempted to sync and loop the same sound.');

  }
  var s = String.fromCharCode(60)+'audio ';
  if(typeof(id)==="string"){ 
    s += 'id=\''+id+'\'  '; 
  }
  if(controls){
    s += ' controls controlsList=\'nodownload\' '; 
  }
  if(loop){ 
    s += ' loop '; 
  }
  s += ' autoplay' + String.fromCharCode(62) +''+src;
  s += String.fromCharCode(60)+'/audio'+String.fromCharCode(62);
  var thisTag = s;
  if(isMobilePlayer()){
    var repl = String.fromCharCode(60);
    repl += 'audio controls controlsList=\'nodownload\' class=\'mob-aud\'';
    thisTag = thisTag.replace(String.fromCharCode(60)+'audio', repl);
    var tag = String.fromCharCode(60)+'p'+String.fromCharCode(62);
    tag += thisTag+''+String.fromCharCode(60);
    tag += '/p'+String.fromCharCode(62);
    addText(tag);
    if(typeof($('.mob-aud').last().on('ended'))==='function'){
      onEndBak = $('.mob-aud').last().on('ended');
    }else{
      onEndBak=function(){};
    }
    $('.mob-aud').last().insertAfter($('#txtCommandDiv')).on('ended',function(){
      onEndBak();
      $(this).remove();
    }).css('margin-top','4px');
  }else if (controls){
    var addon = String.fromCharCode(60)+'p'+String.fromCharCode(62);
    addon += thisTag+''+String.fromCharCode(60)+'/p'+String.fromCharCode(62);
    $("#divOutput").after(addon);
  }else{
    $('body').after(thisTag);
  }
}

var safeBreak = String.fromCharCode(60)+'br/'+String.fromCharCode(62);
var noSoundMsg = safeBreak+'There is no sound playing.';

function endAudioSync(){
  if (typeof(sendCommandBak) === 'function'){sendCommand = sendCommandBak;}
}

function increaseVolume(id){
    var thisAud = document.getElementById(id);
	if(!thisAud){
	  addTextAndScroll(safeBreak+'There is no sound playing.');
	}
	else if(thisAud.volume*10<10){
	  thisAud.volume = (thisAud.volume*10+1)/10;
	  addTextAndScroll(safeBreak+'The volume has been increased.');
	}
	else{
	  addTextAndScroll(safeBreak+'The volume is already at the maximum level.');
	}
}

function increaseAllVolume(){
  $('audio').each(function(){
    if (this.volume!=1){this.volume = this.volume + .1};
  });
}

function decreaseVolume (id) {
  var thisAud = document.getElementById(id);
  if(!thisAud){
    addTextAndScroll(safeBreak+'There is no sound playing.');
  }else if(thisAud.volume*10>0){
    thisAud.volume = (thisAud.volume*10-1)/10;
    addTextAndScroll(safeBreak+ 'The volume has been decreased.');
  }else{
    addTextAndScroll(safeBreak+'The volume is already all the way down.');
  }
}

function decreaseAllVolume(){
  $('audio').each(function(){
    if (this.volume>=0.1){this.volume = this.volume - .1};
  });
}

function endAudioSync(){
  if (typeof(sendCommandBak) === 'function'){
    sendCommand = sendCommandBak;
  }
}

function setAllAudioVolume(vol){
  var audios = document.getElementsByTagName('audio');
  for(aud in audios){
    audios[aud].volume = vol;
  }
}

function setAudioCurrentTime(id,pos){
  document.getElementById(id).currentTime = pos;
}

function pauseAudio(id){
  var thisAud = document.getElementById(id);
  thisAud.pause();
}

function resumePausedAudio(id){
  var thisAud = document.getElementById(id);
  thisAud.play();
}

function restartPausedAudio(id){
  var thisAud = document.getElementById(id);
  thisAud.load();
  thisAud.play()
}

function setAudioVolume(id,vol){
  document.getElementById(id).volume = vol;
}



function muteAudio(id){
  var aud = document.getElementById(id);
  aud.volbak = aud.volume;
  setAudioVolume(id,0);
}


function unmuteAudio(id){
  var aud = document.getElementById(id);
  aud.volume = aud.volbak;
}

function muteAllAudio(){
  $('audio').each(function(){
    $(this).attr('volbak',this.volume);
  });
  var audios = document.getElementsByTagName('audio');
  for(aud in audios){
    if (typeof(audios[aud].volume)!='undefined'){
      audios[aud].volume=0;
    }
  }
}


function unmuteAllAudio(){
  $('audio').each(function(){
    $(this).prop('volume',$(this).attr('volbak'));
  });
}

function pauseAllAudio(){
  var audios = document.getElementsByTagName('audio');
  for(aud in audios){
    audios[aud].pause();
  }
}

function destroyAllAudio(){
  $('audio').remove();
}


function restartAllPausedAudio(){
  var audios = document.getElementsByTagName('audio');
  for(aud in audios){
    audios[aud].audios[aud].play();
  }
}

function setAllAudioVolume(vol){
  var audios = document.getElementsByTagName('audio');
  for(aud in audios){
    audios[aud].volume = vol;
  }
}

function setAudioPosition(id,pos){
  document.getElementById(id).currentTime = pos;
}

function testAudio(s){
    s = s + " onloadstart='ASLEvent(\"AudioLog\",\"Loading \"+$(this).attr(\"src\"));$(this).remove();'";
    s = s + " onerror='ASLEvent(\"AudioLog\",$(this).attr(\"src\")+\" failed to load.\");$(this).remove();'";
    s = s + "/"+Chr(62);
    addText(s);
}
  ]]>
    </js>
  </command>

  <function name="AddVideo" parameters="src, sync, loop, id, controls, autoplay, addscript, callback">
    if (sync and loop) {
      error ("Attempted to loop and sync the same sound!")
    }
    src = GetSrc(src)
    lp = ""
    if (loop){
      lp = " loop "
    }
    ctrls = ""
    if (controls) {
      ctrls = " controls "
    }
    aplay = ""
    if (autoplay) {
      aplay = " autoplay "
    }
    if (id = "") {
      id = CreateVideoID()
    }
    id = Replace(id, " ", "_")
    s = Chr(60) + "video " + ctrls + " " + lp + " " + aplay
    s = s + " style='width:100%;'"
    s = s + "id='" + id + "'" + Chr(62)
    s = s + src
    s = s + Chr(60)+"/video"+Chr(62)
    msg (s)
    if (addscript) {
      SetVideoCallback (id, callback)
    }
    if (sync) {
      DoVideoSync
    }
  </function>

  <function name="HideVideo" parameters="id">
    JS.uiHide(id)
  </function>

  <function name="DestroyVideo" parameters="id">
    JS.eval("$('#"+id+"').remove();")
  </function>

  <function name="ShowHiddenVideo" parameters="id">
    JS.uiShow(id)
  </function>

  <function name="PauseVideo" parameters="id">
    JS.eval("document.getElementById('"+id+"').pause();")
  </function>


  <function name="ResumePausedVideo" parameters="id">
    JS.eval("document.getElementById('"+id+"').play();")
  </function>


  <function name="RestartPausedVideo" parameters="id">
    JS.eval("document.getElementById('"+id+"').load();")
  </function>


  <function name="SetVideoCurrentTime" parameters="id,time">
    JS.eval("document.getElementById('"+id+"').currentTime = "+time+";")
  </function>

  <function name="CreateVideoID" type="string">
    if (not HasAttribute(game,"videofilesplayed")) {
      game.videofilesplayed = 0
    }
    game.videofilesplayed = game.videofilesplayed + 1
    return ("video-" + game.videofilesplayed)
  </function>

  <function name="SetVideoCallback" parameters="id, callback">
    js = "$('#"+id+"').on('ended',function(){ASLEvent('EndVideoSyncAndInvoke',$(this).attr('id'));/*$(this).remove();*/});"
    JS.eval (js)
    if (not HasAttribute(game, "videofinishedcallback")) {
      game.videofinishedcallback = NewScriptDictionary()
    }
    dictionary add (game.videofinishedcallback, id, callback)
  </function>

  <function name="EndVideoSync" parameters="bs">
    game.preventturnscripts = true
    game.videosyncing = false
    JS.endAudioSync()
  </function>

  <function name="EndVideoSyncAndInvoke" parameters="id">
    game.preventturnscripts = true
    game.audiosyncing = false
    JS.endAudioSync()
    if (HasAttribute(game, "videofinishedcallback")) {
      if (DictionaryContains(game.videofinishedcallback,id)) {
        invoke (ScriptDictionaryItem(game.videofinishedcallback,id))
        dictionary remove(game.videofinishedcallback,id)
        if (DictionaryCount(game.videofinishedcallback)>0){
          DoVideoSync
        }
      }
    }
  </function>

  <function name="DoVideoSync">
    firsttime {
      JS.eval ("var sendCommandBak = sendCommand;")
    }
    game.videosyncing = true
    JS.eval ("sendCommand = function(){$('input#txtCommand').val();};")
  </function>

  <function name="DestroyAllVideo">
    JS.eval("$('video').remove();")
  </function>


  <!-- 
  GUI Stuff 
-->

  <editor>
    <appliesto>(function)PlaySound</appliesto>
    <display>Add sound: #0</display>
    <category>[EditorScriptsOutputOutput]</category>
    <create>PlaySound ("", false, false, "", false, false){}</create>
    <add>Add sound (NEW)</add>
    <advanced />

    <control>
      <controltype>label</controltype>
      <caption>[EditorScriptsOutputPlaysound]</caption>
    </control>

    <control>
      <controltype>expression</controltype>
      <attribute>0</attribute>
      <simple>filename</simple>
      <simpleeditor>file</simpleeditor>
      <source>*.wav;*.mp3;*.ogg</source>
      <filefiltername>Sound Files</filefiltername>
    </control>

    <control>
      <controltype>label</controltype>
      <caption>ID (Optional):</caption>
      <breakbefore/>
    </control>

    <control>
      <controltype>textbox</controltype>
      <attribute>3</attribute>
    </control>

    <control>
      <controltype>label</controltype>
      <caption>[EditorScriptsOutputWaitforsound]</caption>
      <breakbefore/>
    </control>

    <control>
      <controltype>expression</controltype>
      <attribute>1</attribute>
      <simpleeditor>boolean</simpleeditor>
    </control>

    <control>
      <controltype>label</controltype>
      <caption>[EditorScriptsOutputLoop]</caption>
    </control>

    <control>
      <controltype>expression</controltype>
      <attribute>2</attribute>
      <simpleeditor>boolean</simpleeditor>
    </control>

    <control>
      <controltype>label</controltype>
      <caption>Show controls</caption>
    </control>

    <control>
      <controltype>expression</controltype>
      <attribute>4</attribute>
      <simpleeditor>boolean</simpleeditor>
    </control>

    <control>
      <controltype>label</controltype>
      <caption>Add a callback script</caption>
      <breakbefore/>
    </control>

    <control>
      <controltype>expression</controltype>
      <attribute>5</attribute>
      <simpleeditor>boolean</simpleeditor>
    </control>

    <control>
      <controltype>label</controltype>
      <caption>
        Script to run after sound has finished  (Optional)

        (You must set "Add a callback script" to yes for this script to run!)
      </caption>
      <breakbefore/>
    </control>

    <control>
      <onlydisplayif>#5</onlydisplayif>
      <controltype>script</controltype>
      <attribute>script</attribute>

    </control>
  </editor>

  <editor>
    <appliesto>(function)DestroyAllAudio</appliesto>
    <display>Destroy all audio</display>
    <category>[EditorScriptsOutputOutput]</category>
    <create>DestroyAllAudio</create>
    <add>Destroy all audio (NEW)</add>
    <advanced />

    <control>
      <controltype>label</controltype>
      <caption>Destroy all audio</caption>
    </control>
  </editor>

  <editor>
    <appliesto>(function)DestroyAudio</appliesto>
    <display>Destroy audio #0</display>
    <category>[EditorScriptsOutputOutput]</category>
    <create>DestroyAudio("")</create>
    <add>Destroy audio (NEW)</add>
    <advanced />

    <control>
      <controltype>label</controltype>
      <caption>Destroy audio with ID:</caption>
    </control>
    <control>
      <controltype>textbox</controltype>
      <attribute>0</attribute>
    </control>
  </editor>



  <editor>
    <appliesto>(function)AddVideo</appliesto>
    <display>Add video: #0</display>
    <category>[EditorScriptsOutputOutput]</category>
    <create>AddVideo ("", false, false, "", true, false, false){}</create>
    <add>Add video (NEW)</add>
    <advanced />

    <control>
      <controltype>label</controltype>
      <caption>Add a video</caption>
    </control>

    <control>
      <controltype>expression</controltype>
      <attribute>0</attribute>
      <simple>filename</simple>
      <simpleeditor>file</simpleeditor>
      <source>*.mp4;*.ogv</source>
      <filefiltername>Video Files</filefiltername>
    </control>

    <control>
      <controltype>label</controltype>
      <caption>ID (Optional):</caption>
      <breakbefore/>
    </control>

    <control>
      <controltype>textbox</controltype>
      <attribute>3</attribute>
    </control>

    <control>
      <controltype>label</controltype>
      <caption>Wait for video to finish playing</caption>
      <breakbefore/>
    </control>

    <control>
      <controltype>expression</controltype>
      <attribute>1</attribute>
      <simpleeditor>boolean</simpleeditor>
    </control>

    <control>
      <controltype>label</controltype>
      <caption>[EditorScriptsOutputLoop]</caption>
    </control>

    <control>
      <controltype>expression</controltype>
      <attribute>2</attribute>
      <simpleeditor>boolean</simpleeditor>
    </control>

    <control>
      <controltype>label</controltype>
      <caption>Show controls</caption>
    </control>

    <control>
      <controltype>expression</controltype>
      <attribute>4</attribute>
      <simpleeditor>boolean</simpleeditor>
    </control>

    <control>
      <controltype>label</controltype>
      <caption>Autoplay</caption>
    </control>

    <control>
      <controltype>expression</controltype>
      <attribute>5</attribute>
      <simpleeditor>boolean</simpleeditor>
    </control>

    <control>
      <controltype>label</controltype>
      <caption>Add a callback script</caption>
    </control>

    <control>
      <controltype>expression</controltype>
      <attribute>6</attribute>
      <simpleeditor>boolean</simpleeditor>
    </control>

    <control>
      <controltype>label</controltype>
      <caption>
        Script to run after video has finished  (Optional)

        (You must set "Add a callback script" to yes for this script to run!)
      </caption>
      <breakbefore/>
    </control>

    <control>
      <onlydisplayif>#5</onlydisplayif>
      <controltype>script</controltype>
      <attribute>script</attribute>

    </control>

  </editor>

  <editor>
    <appliesto>(function)DestroyAllVideo</appliesto>
    <display>Destroy all video</display>
    <category>[EditorScriptsOutputOutput]</category>
    <create>DestroyAllVideo</create>
    <add>Destroy all video (NEW)</add>
    <advanced />

    <control>
      <controltype>label</controltype>
      <caption>Destroy all video</caption>
    </control>
  </editor>

  <editor>
    <appliesto>(function)DestroyVideo</appliesto>
    <display>Destroy video #0</display>
    <category>[EditorScriptsOutputOutput]</category>
    <create>DestroyVideo("")</create>
    <add>Destroy video (NEW)</add>
    <advanced />

    <control>
      <controltype>label</controltype>
      <caption>Destroy video with ID:</caption>
    </control>
    <control>
      <controltype>textbox</controltype>
      <attribute>0</attribute>
    </control>
  </editor>


</library>

K.V.

So, I just played the Vorple demo on my Android phone, and the audio played automatically???

HOW DID THEY DO THAT?!?


Someone see if this also works on an iThing, please!

Just click SOUTH, then the audio should autoplay.

https://vorple-if.com/demo/play.html


+K.V. I did not get any sound on my Kindle.


HOW DID THEY DO THAT?!?

As far as I can tell, it's just an <audio> element, started automatically by calling its .play() method.


I noticed that if the game has the option "clear screen" for every turn, this could be a problem because the game clears everything inserted in the page, including the<audio> statements.
So, remember to NOT enable this option.


This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums