Initial commit
This commit is contained in:
parent
d7833f6660
commit
bb9287793b
577
WaveSurferSB.sbi
Normal file
577
WaveSurferSB.sbi
Normal file
@ -0,0 +1,577 @@
|
||||
; WaveSurferSB - A wavesurfer.js v7 wrapper for SpiderBasic
|
||||
;
|
||||
; This library wraps the wavesurfer.js audio waveform player for use in SpiderBasic.
|
||||
; Includes support for Timeline, Minimap, and Spectrogram plugins.
|
||||
; wavesurfer.js v7: https://wavesurfer.xyz / https://github.com/katspaugh/wavesurfer.js
|
||||
;
|
||||
; Usage:
|
||||
; IncludeFile "WaveSurferSB/WaveSurferSB.sbi"
|
||||
;
|
||||
; ; Load core + plugins (comma-separated: "timeline,minimap,spectrogram")
|
||||
; WaveSurferSB::Download(@MyCallback(), "timeline,minimap,spectrogram")
|
||||
;
|
||||
; Procedure MyCallback(Success)
|
||||
; If Success
|
||||
; Define ws = WaveSurferSB::Create("#myContainer", WaveSurferSB::#DragToSeek)
|
||||
; WaveSurferSB::TimelineCreate(ws)
|
||||
; WaveSurferSB::MinimapCreate(ws, 50, "#777", "#333")
|
||||
; WaveSurferSB::SpectrogramCreate(ws, "", 128, #True)
|
||||
; WaveSurferSB::Load(ws, "audio.mp3")
|
||||
; EndIf
|
||||
; EndProcedure
|
||||
;
|
||||
; For wavesurfer.js documentation, see: https://wavesurfer.xyz/docs
|
||||
|
||||
DeclareModule WaveSurferSB
|
||||
|
||||
;{ Initialization
|
||||
; Plugins.s: comma-separated plugin names to load, e.g. "timeline,minimap,spectrogram"
|
||||
Declare Download(*Callback, Plugins.s = "", UseLocalFiles = #False)
|
||||
;}
|
||||
|
||||
;{ Instance Management
|
||||
Declare Create(Container.s, Flags = 0)
|
||||
Declare Create_ex(Container.s, OptionsJSON.s)
|
||||
Declare Destroy(Instance)
|
||||
Declare Empty(Instance)
|
||||
;}
|
||||
|
||||
;{ Audio Loading
|
||||
Declare Load(Instance, URL.s)
|
||||
Declare LoadWithPeaks(Instance, URL.s, PeaksJSON.s, Duration.d = 0.0)
|
||||
;}
|
||||
|
||||
;{ Playback Control
|
||||
Declare Play(Instance)
|
||||
Declare PlayFrom(Instance, StartSeconds.d, EndSeconds.d = -1.0)
|
||||
Declare Pause(Instance)
|
||||
Declare PlayPause(Instance)
|
||||
Declare Stop(Instance)
|
||||
Declare IsPlaying(Instance)
|
||||
;}
|
||||
|
||||
;{ Navigation
|
||||
Declare SetTime(Instance, TimeSeconds.d)
|
||||
Declare.d GetCurrentTime(Instance)
|
||||
Declare.d GetDuration(Instance)
|
||||
Declare SeekTo(Instance, Progress.d)
|
||||
;}
|
||||
|
||||
;{ Volume & Speed
|
||||
Declare SetVolume(Instance, Volume.d)
|
||||
Declare.d GetVolume(Instance)
|
||||
Declare SetMuted(Instance, Muted)
|
||||
Declare SetPlaybackRate(Instance, Rate.d)
|
||||
Declare.d GetPlaybackRate(Instance)
|
||||
;}
|
||||
|
||||
;{ Visual Options
|
||||
Declare SetOptions(Instance, OptionsJSON.s)
|
||||
Declare Zoom(Instance, MinPxPerSec.d)
|
||||
;}
|
||||
|
||||
;{ Generic Plugin Registration
|
||||
Declare RegisterPlugin(Instance, PluginName.s, OptionsJSON.s = "{}")
|
||||
Declare DestroyPlugin(PluginInstance)
|
||||
;}
|
||||
|
||||
;{ Timeline Plugin
|
||||
Declare TimelineCreate(Instance, Container.s = "", Height = 20)
|
||||
Declare TimelineCreate_ex(Instance, OptionsJSON.s)
|
||||
Declare TimelineDestroy(PluginInstance)
|
||||
;}
|
||||
|
||||
;{ Minimap Plugin
|
||||
Declare MinimapCreate(Instance, Height = 50, WaveColor.s = "#999", ProgressColor.s = "#555", OverlayColor.s = "")
|
||||
Declare MinimapCreate_ex(Instance, OptionsJSON.s)
|
||||
Declare MinimapDestroy(PluginInstance)
|
||||
;}
|
||||
|
||||
;{ Spectrogram Plugin
|
||||
Declare SpectrogramCreate(Instance, Container.s = "", Height = 128, Labels = #False)
|
||||
Declare SpectrogramCreate_ex(Instance, OptionsJSON.s)
|
||||
Declare SpectrogramDestroy(PluginInstance)
|
||||
;}
|
||||
|
||||
;{ Events
|
||||
Declare OnReady(Instance, *Callback)
|
||||
Declare OnPlay(Instance, *Callback)
|
||||
Declare OnPause(Instance, *Callback)
|
||||
Declare OnFinish(Instance, *Callback)
|
||||
Declare OnTimeUpdate(Instance, *Callback)
|
||||
Declare OnSeeking(Instance, *Callback)
|
||||
Declare OnInteraction(Instance, *Callback)
|
||||
Declare OnClick(Instance, *Callback)
|
||||
Declare OnDecode(Instance, *Callback)
|
||||
Declare OnLoading(Instance, *Callback)
|
||||
Declare OnDestroy(Instance, *Callback)
|
||||
Declare OnEvent(Instance, EventName.s, *Callback)
|
||||
;}
|
||||
|
||||
;{ Data Export
|
||||
Declare.s GetMediaElement(Instance)
|
||||
;}
|
||||
|
||||
;{ Creation Flag Constants
|
||||
#Default = 0
|
||||
#Normalize = 1 << 0
|
||||
#AutoPlay = 1 << 1
|
||||
#DragToSeek = 1 << 2
|
||||
#HideScrollbar = 1 << 3
|
||||
#AutoScroll = 1 << 4
|
||||
#AutoCenter = 1 << 5
|
||||
#SplitChannels = 1 << 6
|
||||
#BarStyle = 1 << 7
|
||||
;}
|
||||
|
||||
EndDeclareModule
|
||||
|
||||
Module WaveSurferSB
|
||||
EnableExplicit
|
||||
|
||||
;{ Private Variables
|
||||
Global download_callback
|
||||
Global is_loaded = #False
|
||||
Global plugins_to_load.s = ""
|
||||
Global use_local.i = #False
|
||||
;}
|
||||
|
||||
;{ Private Declarations
|
||||
Declare Handler_Download(url.s, success)
|
||||
Declare Handler_PluginDownload(url.s, success)
|
||||
Declare _HideAMD()
|
||||
Declare _RestoreAMD()
|
||||
Declare _LoadNextPlugin()
|
||||
;}
|
||||
|
||||
; AMD/UMD Helpers
|
||||
Procedure _HideAMD()
|
||||
!window._ws_saved_module = (typeof module !== 'undefined') ? module : undefined;
|
||||
!window._ws_saved_exports = (typeof exports !== 'undefined') ? exports : undefined;
|
||||
!window._ws_saved_define = (typeof define !== 'undefined') ? define : undefined;
|
||||
!try { module = undefined; } catch(e) {}
|
||||
!try { exports = undefined; } catch(e) {}
|
||||
!try { define = undefined; } catch(e) {}
|
||||
EndProcedure
|
||||
|
||||
Procedure _RestoreAMD()
|
||||
!try { if (window._ws_saved_module !== undefined) module = window._ws_saved_module; } catch(e) {}
|
||||
!try { if (window._ws_saved_exports !== undefined) exports = window._ws_saved_exports; } catch(e) {}
|
||||
!try { if (window._ws_saved_define !== undefined) define = window._ws_saved_define; } catch(e) {}
|
||||
EndProcedure
|
||||
|
||||
; Plugin Loading Chain
|
||||
Procedure _LoadNextPlugin()
|
||||
Protected plugin.s, url.s
|
||||
|
||||
; Pop the first plugin from the comma-separated list
|
||||
!v_plugin = wavesurfersb$g_plugins_to_load.split(',')[0] || '';
|
||||
!wavesurfersb$g_plugins_to_load = wavesurfersb$g_plugins_to_load.split(',').slice(1).join(',');
|
||||
|
||||
!v_plugin = v_plugin.trim();
|
||||
|
||||
Protected check
|
||||
!v_check = (v_plugin === '');
|
||||
|
||||
If check
|
||||
; All plugins loaded - restore AMD and call user callback
|
||||
_RestoreAMD()
|
||||
is_loaded = #True
|
||||
!wavesurfersb$g_download_callback(1);
|
||||
ProcedureReturn
|
||||
EndIf
|
||||
|
||||
If use_local
|
||||
url = "LocalFiles/JS/wavesurfer-" + plugin + ".min.js"
|
||||
Else
|
||||
url = "https://unpkg.com/wavesurfer.js@7/dist/plugins/" + plugin + ".min.js"
|
||||
EndIf
|
||||
|
||||
LoadScript(url, @Handler_PluginDownload(), #PB_Script_JavaScript)
|
||||
EndProcedure
|
||||
|
||||
; Initialization
|
||||
Procedure Download(*Callback, Plugins.s = "", UseLocalFiles = #False)
|
||||
download_callback = *Callback
|
||||
plugins_to_load = Plugins
|
||||
use_local = UseLocalFiles
|
||||
|
||||
_HideAMD()
|
||||
|
||||
If UseLocalFiles
|
||||
LoadScript("LocalFiles/JS/wavesurfer.min.js", @Handler_Download(), #PB_Script_JavaScript)
|
||||
Else
|
||||
LoadScript("https://unpkg.com/wavesurfer.js@7/dist/wavesurfer.min.js", @Handler_Download(), #PB_Script_JavaScript)
|
||||
EndIf
|
||||
EndProcedure
|
||||
|
||||
; Instance Management
|
||||
Procedure Create(Container.s, Flags = 0)
|
||||
Protected Instance
|
||||
|
||||
; Build options object in JavaScript
|
||||
!var _opts = { container: v_container };
|
||||
|
||||
If Flags & #Normalize
|
||||
!_opts.normalize = true;
|
||||
EndIf
|
||||
|
||||
If Flags & #AutoPlay
|
||||
!_opts.autoplay = true;
|
||||
EndIf
|
||||
|
||||
If Flags & #DragToSeek
|
||||
!_opts.dragToSeek = true;
|
||||
EndIf
|
||||
|
||||
If Flags & #HideScrollbar
|
||||
!_opts.hideScrollbar = true;
|
||||
EndIf
|
||||
|
||||
If Flags & #AutoScroll
|
||||
!_opts.autoScroll = true;
|
||||
EndIf
|
||||
|
||||
If Flags & #AutoCenter
|
||||
!_opts.autoCenter = true;
|
||||
EndIf
|
||||
|
||||
If Flags & #SplitChannels
|
||||
!_opts.splitChannels = [{}];
|
||||
EndIf
|
||||
|
||||
If Flags & #BarStyle
|
||||
!_opts.barWidth = 2;
|
||||
!_opts.barGap = 1;
|
||||
!_opts.barRadius = 2;
|
||||
EndIf
|
||||
|
||||
!v_instance = WaveSurfer.create(_opts);
|
||||
ProcedureReturn Instance
|
||||
EndProcedure
|
||||
|
||||
Procedure Create_ex(Container.s, OptionsJSON.s)
|
||||
Protected Instance
|
||||
|
||||
!var _opts;
|
||||
!try { _opts = JSON.parse(v_optionsjson); } catch(e) { _opts = {}; }
|
||||
!_opts.container = v_container;
|
||||
!v_instance = WaveSurfer.create(_opts);
|
||||
|
||||
ProcedureReturn Instance
|
||||
EndProcedure
|
||||
|
||||
Procedure Destroy(Instance)
|
||||
!if (v_instance && typeof v_instance.destroy === 'function') {
|
||||
! v_instance.destroy();
|
||||
!}
|
||||
EndProcedure
|
||||
|
||||
Procedure Empty(Instance)
|
||||
!if (v_instance && typeof v_instance.empty === 'function') {
|
||||
! v_instance.empty();
|
||||
!}
|
||||
EndProcedure
|
||||
|
||||
; Audio Loading
|
||||
Procedure Load(Instance, URL.s)
|
||||
!if (v_instance) v_instance.load(v_url);
|
||||
EndProcedure
|
||||
|
||||
Procedure LoadWithPeaks(Instance, URL.s, PeaksJSON.s, Duration.d = 0.0)
|
||||
!if (v_instance) {
|
||||
! var _peaks;
|
||||
! try { _peaks = JSON.parse(v_peaksjson); } catch(e) { _peaks = undefined; }
|
||||
! var _dur = v_duration > 0 ? v_duration : undefined;
|
||||
! v_instance.load(v_url, _peaks, _dur);
|
||||
!}
|
||||
EndProcedure
|
||||
|
||||
; Playback Control
|
||||
Procedure Play(Instance)
|
||||
!if (v_instance) v_instance.play();
|
||||
EndProcedure
|
||||
|
||||
Procedure PlayFrom(Instance, StartSeconds.d, EndSeconds.d = -1.0)
|
||||
!if (v_instance) {
|
||||
! if (v_endseconds >= 0) {
|
||||
! v_instance.play(v_startseconds, v_endseconds);
|
||||
! } else {
|
||||
! v_instance.play(v_startseconds);
|
||||
! }
|
||||
!}
|
||||
EndProcedure
|
||||
|
||||
Procedure Pause(Instance)
|
||||
!if (v_instance) v_instance.pause();
|
||||
EndProcedure
|
||||
|
||||
Procedure PlayPause(Instance)
|
||||
!if (v_instance) v_instance.playPause();
|
||||
EndProcedure
|
||||
|
||||
Procedure Stop(Instance)
|
||||
!if (v_instance) v_instance.stop();
|
||||
EndProcedure
|
||||
|
||||
Procedure IsPlaying(Instance)
|
||||
Protected Result = #False
|
||||
!if (v_instance) v_result = v_instance.isPlaying();
|
||||
ProcedureReturn Result
|
||||
EndProcedure
|
||||
|
||||
; Navigation
|
||||
Procedure SetTime(Instance, TimeSeconds.d)
|
||||
!if (v_instance) v_instance.setTime(v_timeseconds);
|
||||
EndProcedure
|
||||
|
||||
Procedure.d GetCurrentTime(Instance)
|
||||
Protected.d Result = 0.0
|
||||
!if (v_instance) v_result = v_instance.getCurrentTime();
|
||||
ProcedureReturn Result
|
||||
EndProcedure
|
||||
|
||||
Procedure.d GetDuration(Instance)
|
||||
Protected.d Result = 0.0
|
||||
!if (v_instance) v_result = v_instance.getDuration();
|
||||
ProcedureReturn Result
|
||||
EndProcedure
|
||||
|
||||
Procedure SeekTo(Instance, Progress.d)
|
||||
!if (v_instance) v_instance.seekTo(v_progress);
|
||||
EndProcedure
|
||||
|
||||
; Volume & Speed
|
||||
Procedure SetVolume(Instance, Volume.d)
|
||||
!if (v_instance) v_instance.setVolume(v_volume);
|
||||
EndProcedure
|
||||
|
||||
Procedure.d GetVolume(Instance)
|
||||
Protected.d Result = 1.0
|
||||
!if (v_instance) v_result = v_instance.getVolume();
|
||||
ProcedureReturn Result
|
||||
EndProcedure
|
||||
|
||||
Procedure SetMuted(Instance, Muted)
|
||||
!if (v_instance) v_instance.setMuted(!!v_muted);
|
||||
EndProcedure
|
||||
|
||||
Procedure SetPlaybackRate(Instance, Rate.d)
|
||||
!if (v_instance) v_instance.setPlaybackRate(v_rate);
|
||||
EndProcedure
|
||||
|
||||
Procedure.d GetPlaybackRate(Instance)
|
||||
Protected.d Result = 1.0
|
||||
!if (v_instance) v_result = v_instance.getPlaybackRate();
|
||||
ProcedureReturn Result
|
||||
EndProcedure
|
||||
|
||||
; Visual Options
|
||||
Procedure SetOptions(Instance, OptionsJSON.s)
|
||||
!if (v_instance) {
|
||||
! var _opts;
|
||||
! try { _opts = JSON.parse(v_optionsjson); } catch(e) { _opts = {}; }
|
||||
! v_instance.setOptions(_opts);
|
||||
!}
|
||||
EndProcedure
|
||||
|
||||
Procedure Zoom(Instance, MinPxPerSec.d)
|
||||
!if (v_instance) v_instance.zoom(v_minpxpersec);
|
||||
EndProcedure
|
||||
|
||||
; Generic Plugin Registration
|
||||
Procedure RegisterPlugin(Instance, PluginName.s, OptionsJSON.s = "{}")
|
||||
Protected PluginInstance
|
||||
!if (v_instance && WaveSurfer[v_pluginname]) {
|
||||
! var _opts;
|
||||
! try { _opts = JSON.parse(v_optionsjson); } catch(e) { _opts = {}; }
|
||||
! v_plugininstance = v_instance.registerPlugin(WaveSurfer[v_pluginname].create(_opts));
|
||||
!}
|
||||
ProcedureReturn PluginInstance
|
||||
EndProcedure
|
||||
|
||||
Procedure DestroyPlugin(PluginInstance)
|
||||
!if (v_plugininstance && typeof v_plugininstance.destroy === 'function') {
|
||||
! v_plugininstance.destroy();
|
||||
!}
|
||||
EndProcedure
|
||||
|
||||
; Timeline Plugin
|
||||
Procedure TimelineCreate(Instance, Container.s = "", Height = 20)
|
||||
Protected PluginInstance
|
||||
!if (v_instance && WaveSurfer.Timeline) {
|
||||
! var _opts = { height: v_height };
|
||||
! if (v_container && v_container !== '') _opts.container = v_container;
|
||||
! v_plugininstance = v_instance.registerPlugin(WaveSurfer.Timeline.create(_opts));
|
||||
!}
|
||||
ProcedureReturn PluginInstance
|
||||
EndProcedure
|
||||
|
||||
Procedure TimelineCreate_ex(Instance, OptionsJSON.s)
|
||||
Protected PluginInstance
|
||||
!if (v_instance && WaveSurfer.Timeline) {
|
||||
! var _opts;
|
||||
! try { _opts = JSON.parse(v_optionsjson); } catch(e) { _opts = {}; }
|
||||
! v_plugininstance = v_instance.registerPlugin(WaveSurfer.Timeline.create(_opts));
|
||||
!}
|
||||
ProcedureReturn PluginInstance
|
||||
EndProcedure
|
||||
|
||||
Procedure TimelineDestroy(PluginInstance)
|
||||
DestroyPlugin(PluginInstance)
|
||||
EndProcedure
|
||||
|
||||
; Minimap Plugin
|
||||
Procedure MinimapCreate(Instance, Height = 50, WaveColor.s = "#999", ProgressColor.s = "#555", OverlayColor.s = "")
|
||||
Protected PluginInstance
|
||||
!if (v_instance && WaveSurfer.Minimap) {
|
||||
! var _opts = {
|
||||
! height: v_height,
|
||||
! waveColor: v_wavecolor,
|
||||
! progressColor: v_progresscolor
|
||||
! };
|
||||
! if (v_overlaycolor && v_overlaycolor !== '') _opts.overlayColor = v_overlaycolor;
|
||||
! v_plugininstance = v_instance.registerPlugin(WaveSurfer.Minimap.create(_opts));
|
||||
!}
|
||||
ProcedureReturn PluginInstance
|
||||
EndProcedure
|
||||
|
||||
Procedure MinimapCreate_ex(Instance, OptionsJSON.s)
|
||||
Protected PluginInstance
|
||||
!if (v_instance && WaveSurfer.Minimap) {
|
||||
! var _opts;
|
||||
! try { _opts = JSON.parse(v_optionsjson); } catch(e) { _opts = {}; }
|
||||
! v_plugininstance = v_instance.registerPlugin(WaveSurfer.Minimap.create(_opts));
|
||||
!}
|
||||
ProcedureReturn PluginInstance
|
||||
EndProcedure
|
||||
|
||||
Procedure MinimapDestroy(PluginInstance)
|
||||
DestroyPlugin(PluginInstance)
|
||||
EndProcedure
|
||||
|
||||
; Spectrogram Plugin
|
||||
Procedure SpectrogramCreate(Instance, Container.s = "", Height = 128, Labels = #False)
|
||||
Protected PluginInstance
|
||||
!if (v_instance && WaveSurfer.Spectrogram) {
|
||||
! var _opts = {
|
||||
! height: v_height,
|
||||
! labels: !!v_labels
|
||||
! };
|
||||
! if (v_container && v_container !== '') _opts.container = v_container;
|
||||
! v_plugininstance = v_instance.registerPlugin(WaveSurfer.Spectrogram.create(_opts));
|
||||
!}
|
||||
ProcedureReturn PluginInstance
|
||||
EndProcedure
|
||||
|
||||
Procedure SpectrogramCreate_ex(Instance, OptionsJSON.s)
|
||||
Protected PluginInstance
|
||||
!if (v_instance && WaveSurfer.Spectrogram) {
|
||||
! var _opts;
|
||||
! try { _opts = JSON.parse(v_optionsjson); } catch(e) { _opts = {}; }
|
||||
! v_plugininstance = v_instance.registerPlugin(WaveSurfer.Spectrogram.create(_opts));
|
||||
!}
|
||||
ProcedureReturn PluginInstance
|
||||
EndProcedure
|
||||
|
||||
Procedure SpectrogramDestroy(PluginInstance)
|
||||
DestroyPlugin(PluginInstance)
|
||||
EndProcedure
|
||||
|
||||
; Events
|
||||
Procedure OnReady(Instance, *Callback)
|
||||
!if (v_instance) v_instance.on('ready', function(duration) { p_callback(duration); });
|
||||
EndProcedure
|
||||
|
||||
Procedure OnPlay(Instance, *Callback)
|
||||
!if (v_instance) v_instance.on('play', function() { p_callback(); });
|
||||
EndProcedure
|
||||
|
||||
Procedure OnPause(Instance, *Callback)
|
||||
!if (v_instance) v_instance.on('pause', function() { p_callback(); });
|
||||
EndProcedure
|
||||
|
||||
Procedure OnFinish(Instance, *Callback)
|
||||
!if (v_instance) v_instance.on('finish', function() { p_callback(); });
|
||||
EndProcedure
|
||||
|
||||
Procedure OnTimeUpdate(Instance, *Callback)
|
||||
!if (v_instance) v_instance.on('timeupdate', function(currentTime) { p_callback(currentTime); });
|
||||
EndProcedure
|
||||
|
||||
Procedure OnSeeking(Instance, *Callback)
|
||||
!if (v_instance) v_instance.on('seeking', function(currentTime) { p_callback(currentTime); });
|
||||
EndProcedure
|
||||
|
||||
Procedure OnInteraction(Instance, *Callback)
|
||||
!if (v_instance) v_instance.on('interaction', function(newTime) { p_callback(newTime); });
|
||||
EndProcedure
|
||||
|
||||
Procedure OnClick(Instance, *Callback)
|
||||
!if (v_instance) v_instance.on('click', function(relativeX) { p_callback(relativeX); });
|
||||
EndProcedure
|
||||
|
||||
Procedure OnDecode(Instance, *Callback)
|
||||
!if (v_instance) v_instance.on('decode', function(duration) { p_callback(duration); });
|
||||
EndProcedure
|
||||
|
||||
Procedure OnLoading(Instance, *Callback)
|
||||
!if (v_instance) v_instance.on('loading', function(percent) { p_callback(percent); });
|
||||
EndProcedure
|
||||
|
||||
Procedure OnDestroy(Instance, *Callback)
|
||||
!if (v_instance) v_instance.on('destroy', function() { p_callback(); });
|
||||
EndProcedure
|
||||
|
||||
Procedure OnEvent(Instance, EventName.s, *Callback)
|
||||
!if (v_instance) v_instance.on(v_eventname, function() { p_callback(); });
|
||||
EndProcedure
|
||||
|
||||
; Data Export
|
||||
Procedure.s GetMediaElement(Instance)
|
||||
Protected Result.s = ""
|
||||
!if (v_instance) {
|
||||
! var _media = v_instance.getMediaElement();
|
||||
! if (_media) v_result = _media.outerHTML || '';
|
||||
!}
|
||||
ProcedureReturn Result
|
||||
EndProcedure
|
||||
|
||||
; Private Procedures
|
||||
Procedure Handler_Download(url.s, success)
|
||||
If success
|
||||
; Core loaded - now load plugins if any
|
||||
If plugins_to_load <> ""
|
||||
_LoadNextPlugin()
|
||||
Else
|
||||
; No plugins requested - all done
|
||||
_RestoreAMD()
|
||||
is_loaded = #True
|
||||
!wavesurfersb$g_download_callback(1);
|
||||
EndIf
|
||||
Else
|
||||
_RestoreAMD()
|
||||
!wavesurfersb$g_download_callback(0);
|
||||
EndIf
|
||||
EndProcedure
|
||||
|
||||
Procedure Handler_PluginDownload(url.s, success)
|
||||
If success
|
||||
; Plugin loaded - continue chain with next plugin
|
||||
_LoadNextPlugin()
|
||||
Else
|
||||
_RestoreAMD()
|
||||
!wavesurfersb$g_download_callback(0);
|
||||
EndIf
|
||||
EndProcedure
|
||||
|
||||
EndModule
|
||||
|
||||
; IDE Options = SpiderBasic 3.20 (Windows - x86)
|
||||
; Folding = BAAAAAAAAAAg
|
||||
; iOSAppOrientation = 0
|
||||
; AndroidAppCode = 0
|
||||
; AndroidAppOrientation = 0
|
||||
; EnableXP
|
||||
; DPIAware
|
||||
; CompileSourceDirectory
|
||||
144
WaveSurferSB_Plugins_Example_1.sb
Normal file
144
WaveSurferSB_Plugins_Example_1.sb
Normal file
@ -0,0 +1,144 @@
|
||||
; WaveSurferSB Plugins Example
|
||||
; Demonstrates Timeline, Minimap, and Spectrogram plugins
|
||||
;
|
||||
; This example loads wavesurfer.js core + all three plugins,
|
||||
; creates a waveform with playback controls, and attaches each plugin.
|
||||
|
||||
IncludeFile "WaveSurferSB.sbi"
|
||||
|
||||
Global ws ; WaveSurfer instance
|
||||
Global wsTimeline ; Timeline plugin instance
|
||||
Global wsMinimap ; Minimap plugin instance
|
||||
Global wsSpectro ; Spectrogram plugin instance
|
||||
|
||||
Enumeration
|
||||
#btnPlay
|
||||
#btnPause
|
||||
#btnStop
|
||||
#txtStatus
|
||||
#txtTime
|
||||
EndEnumeration
|
||||
|
||||
; ---- Event Callbacks ----
|
||||
|
||||
Procedure OnReady(Duration.d)
|
||||
Debug "Audio ready! Duration: " + StrD(Duration, 2) + "s"
|
||||
SetGadgetText(#txtStatus, "Ready - " + StrD(Duration, 1) + "s")
|
||||
EndProcedure
|
||||
|
||||
Procedure OnTimeUpdate(CurrentTime.d)
|
||||
SetGadgetText(#txtTime, StrD(CurrentTime, 1) + " / " + StrD(WaveSurferSB::GetDuration(ws), 1))
|
||||
EndProcedure
|
||||
|
||||
Procedure OnFinish()
|
||||
SetGadgetText(#txtStatus, "Finished")
|
||||
EndProcedure
|
||||
|
||||
; ---- Button Events ----
|
||||
|
||||
Procedure OnEvent()
|
||||
Select EventGadget()
|
||||
Case #btnPlay
|
||||
WaveSurferSB::Play(ws)
|
||||
SetGadgetText(#txtStatus, "Playing")
|
||||
|
||||
Case #btnPause
|
||||
WaveSurferSB::Pause(ws)
|
||||
SetGadgetText(#txtStatus, "Paused")
|
||||
|
||||
Case #btnStop
|
||||
WaveSurferSB::Stop(ws)
|
||||
SetGadgetText(#txtStatus, "Stopped")
|
||||
EndSelect
|
||||
EndProcedure
|
||||
|
||||
; ---- Download Callback ----
|
||||
|
||||
Procedure OnDownloadComplete(Success)
|
||||
If Not Success
|
||||
Debug "ERROR: Failed to load wavesurfer.js or plugins"
|
||||
SetGadgetText(#txtStatus, "Load failed!")
|
||||
ProcedureReturn
|
||||
EndIf
|
||||
|
||||
Debug "wavesurfer.js + plugins loaded successfully"
|
||||
|
||||
; Create the main WaveSurfer instance with drag-to-seek and bar style
|
||||
ws = WaveSurferSB::Create("#waveform", WaveSurferSB::#DragToSeek | WaveSurferSB::#BarStyle)
|
||||
|
||||
; ---- Attach Plugins ----
|
||||
|
||||
; Timeline: time labels below the waveform (default container, 20px height)
|
||||
wsTimeline = WaveSurferSB::TimelineCreate(ws)
|
||||
|
||||
; Minimap: overview navigation bar with colored overlay
|
||||
wsMinimap = WaveSurferSB::MinimapCreate(ws, 40, "#888", "#444", "rgba(100,100,200,0.3)")
|
||||
|
||||
; Spectrogram: frequency visualization with labels
|
||||
; Renders into the #spectrogram div, 150px tall, with frequency labels
|
||||
wsSpectro = WaveSurferSB::SpectrogramCreate(ws, "#spectrogram", 150, #True)
|
||||
|
||||
; ---- Advanced plugin example using _ex (JSON options) ----
|
||||
; If you need full control, use the _ex variants instead:
|
||||
;
|
||||
; wsTimeline = WaveSurferSB::TimelineCreate_ex(ws, ~"{\"height\": 25, \"timeInterval\": 5, \"primaryLabelInterval\": 10, \"insertPosition\": \"beforebegin\"}")
|
||||
;
|
||||
; wsSpectro = WaveSurferSB::SpectrogramCreate_ex(ws, ~"{\"container\": \"#spectrogram\", \"height\": 200, \"labels\": true, \"fftSamples\": 1024, \"scale\": \"mel\", \"colorMap\": \"roseus\"}")
|
||||
|
||||
; ---- Bind Events ----
|
||||
WaveSurferSB::OnReady(ws, @OnReady())
|
||||
WaveSurferSB::OnTimeUpdate(ws, @OnTimeUpdate())
|
||||
WaveSurferSB::OnFinish(ws, @OnFinish())
|
||||
|
||||
; ---- Load Audio ----
|
||||
; Replace with your audio URL
|
||||
WaveSurferSB::Load(ws, "WaveSurferTestMusic.ogg")
|
||||
|
||||
SetGadgetText(#txtStatus, "Loading audio...")
|
||||
EndProcedure
|
||||
|
||||
; ---- Main UI ----
|
||||
|
||||
Procedure Main()
|
||||
|
||||
OpenWindow(0, 0, 0, 800, 600, "WaveSurferSB - Plugins Demo", #PB_Window_ScreenCentered)
|
||||
|
||||
; Create HTML containers for the waveform and spectrogram
|
||||
; The waveform div holds the main wave + timeline + minimap (auto-appended)
|
||||
; The spectrogram div is separate so it renders below
|
||||
!var _wsRoot = document.body.firstElementChild || document.body;
|
||||
!_wsRoot.insertAdjacentHTML('afterbegin',
|
||||
! '<div id="waveform" style="width:100%; margin:10px 0; border:1px solid #ccc; border-radius:4px; overflow:hidden;"></div>' +
|
||||
! '<div id="spectrogram" style="width:100%; margin:10px 0;"></div>'
|
||||
!);
|
||||
|
||||
; Transport controls
|
||||
ButtonGadget(#btnPlay, 10, 420, 80, 30, "Play")
|
||||
ButtonGadget(#btnPause, 100, 420, 80, 30, "Pause")
|
||||
ButtonGadget(#btnStop, 190, 420, 80, 30, "Stop")
|
||||
|
||||
TextGadget(#txtStatus, 290, 425, 200, 25, "Loading...")
|
||||
TextGadget(#txtTime, 500, 425, 200, 25, "0.0 / 0.0")
|
||||
|
||||
BindGadgetEvent(#btnPlay, @OnEvent())
|
||||
BindGadgetEvent(#btnPause, @OnEvent())
|
||||
BindGadgetEvent(#btnStop, @OnEvent())
|
||||
|
||||
; Download core + all three plugins (loaded sequentially)
|
||||
; Plugin names must match the filenames on unpkg CDN
|
||||
WaveSurferSB::Download(@OnDownloadComplete(), "timeline,minimap,spectrogram")
|
||||
|
||||
EndProcedure
|
||||
|
||||
Main()
|
||||
|
||||
; IDE Options = SpiderBasic 3.20 (Windows - x86)
|
||||
; CursorPosition = 94
|
||||
; FirstLine = 57
|
||||
; Folding = --
|
||||
; iOSAppOrientation = 0
|
||||
; AndroidAppCode = 0
|
||||
; AndroidAppOrientation = 0
|
||||
; EnableXP
|
||||
; DPIAware
|
||||
; CompileSourceDirectory
|
||||
BIN
WaveSurferTestMusic.ogg
Normal file
BIN
WaveSurferTestMusic.ogg
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user