ONO::Lib::Audio::Object

package ONO::Lib::Audio::Object;
################################################################################
# COPYRIGHT / LICENSE #
################################################################################
#
# This file is part of the ONO Software Project.
#
# Copyright (C) 2000-2025 Jos KIRPS [ www.kirps.com | jos_AT_kirps_DOT_com ]
# and The Joopita Project [ www.joopita.org | contact_AT_joopita_DOT_com ]
#
# This file, as well as other parts of the ONO Software Project or related
# elements, are FREE SOFTWARE available under the ARTISTIC LICENSE 2.0.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# For the full license, see /ono/osr/license/LICENSE.txt, or write to
# jos_AT_kirps_DOT_com or contact_AT_joopita_DOT_com.
#
################################################################################
# END OF COPYRIGHT / LICENSE, HERE COMES THE CODE ... #
################################################################################

use strict;
use ONO::Lib::Code::RandomID;
use ONO::Lib::Web::ToolBox;
use ONO::IO;

sub get {

my (
$self,
$file,
$width,
$height,
$switches,
$BASE,
) = @_;

#: Simple HTML5 based audio player, includes support for C64 SID files.
#:
#: -c center

$file =~ s~^//~/~;
my $MIME = &mime("",$file);

my $AUDIO = qq~<audio controls="controls" style="width:${width}px">
<source src="$file" type="$MIME">
<embed style="width:${width}px" src="$file">
</audio>
~;

if ($file =~ /\.sid$/) {
$AUDIO = qq~<a class="button_green disabled" href="#" id="play"><img class="inline24" src="$BASE/ono/osr/images/arrows/nuvola/white/nav_next.png" alt=""></a>
<a class="button_red disabled" href="#" id="stop"><img class="inline24" src="$BASE/ono/osr/images/arrows/nuvola/white/nav_stop.png" alt=""></a>
<div class="hide">
<input type="radio" name="quality" id="optionsQualityGood" value="good" checked>
<input type="radio" name="quality" id="optionsQualityBetter" value="better">
<input type="radio" name="quality" id="optionsQualityBest" value="best">
<input type="radio" name="sidmodel" id="optionsModel6581" value="6581" checked>
<input type="radio" name="sidmodel" id="optionsModel8580" value="8580">
<input type="radio" name="sidfreq" id="optionsFreqPAL" value="PAL" checked>
<input type="radio" name="sidfreq" id="optionsFreqNTSC" value="NTSC">
<!-- Works in Firefox/Chrome on desktop + ios6+ and android, No IE support until IE 12 -->
</div>
<script src="$BASE/ono/osr/javascript/jquery/jquery.js"></script>
<script src="$BASE/ono/osr/javascript/jssid/js/bootstrap.min.js"></script>
<script src="$BASE/ono/osr/javascript/jssid/js/jsxcompressor.js"></script>
<script src="$BASE/ono/osr/javascript/jssid/js/stream.js"></script>
<script src="$BASE/ono/osr/javascript/jssid/js/jssid.core.js"></script>
<script src="$BASE/ono/osr/javascript/jssid/js/jssid.resid.js"></script>
<script src="$BASE/ono/osr/javascript/jssid/js/jssid.mos6510.js"></script>
<script src="$BASE/ono/osr/javascript/jssid/js/jssid.sidplayer.js"></script>
<script src="$BASE/ono/osr/javascript/jssid/js/jssid.dmpplayer.js"></script>
<script src="$BASE/ono/osr/javascript/jssid/js/pico.dev.js"></script>
<script src="$BASE/ono/osr/javascript/jssid/ono.js"></script>
<script>playsid('$BASE$file');</script>
~;
}

if ($switches =~ /c/) {
$AUDIO = qq~<div class="inline auto">$AUDIO</div>~;
}

return $AUDIO;

}

sub icon {

my (
$self,
$id,
$file,
$size,
$switches,
) = @_;

#: Icon based simple audio player
#:
#: -G green led
#: -R red led
#: -Y yellow led

if (!$id) {
$id = ONO::Lib::Code::RandomID->make();
}
my $dir = "32x32";
if ($size > 32) {
$dir = "64x64";
}
my $LED;
if ($switches) {
if ($switches =~ /G/) {
$LED = "green";
}
if ($switches =~ /R/) {
$LED = "red";
}
if ($switches =~ /Y/) {
$LED = "yellow";
}
$LED = qq~<img class="block10 abs" src="/ono/osr/images/leds/16x16/$LED.png" style="right:4px;bottom:0px" alt="">~;
}

return qq~<a href="javascript:void(0);" onclick="onojs_audio_play('$id');">
<div id="${id}_icon" class="block$size rel trans30"><img class="block$size" src="/ono/osr/images/icons/nuovext/$dir/apps/artsbuilder.png" alt="">$LED</div>
</a>
<div class="hide"><audio id="$id" src="$file" preload="auto"></audio></div>
<script>document.getElementById('$id').onloadeddata = function() {onojs_class('${id}_icon','block$size rel')}</script>
~;

}

sub player {

my (
$self,
$id,
$file,
$switches,
$ctrl,
$script_url,
$BLK_ref,
) = @_;

#: The ONO Audio Player module.
#:
#: -a autoplay
#: -b box with rounded corners
#: -B box with rounded corners, color adjusted
#: -C controls (save/del, currently only with -I, requires script_url)
#: -i info (reserved - not implemented yet, not used yet)
#: -I icon (currently requires name)
#: -L large (auto-size)
#: -s small
#: -m mini
#: -n show filename
#: -N filename: simplify (requires -n)
#: -U filename: uppercase (requires -n)
#: -X filename: no extension (requires -n)
#:
#: ctrl, which allows for a second set of switches:
#:
#: -d delete
#: -l load (not implemented yet)
#: -s save

if (!$id) {
$id = "player2";
}

my %BLK;
if ($BLK_ref) {
%BLK = %$BLK_ref;
}

my $MIME = &mime("",$file);
my $MORE;
if ($switches =~ /a/) {
$MORE .= " autoplay";
}
my $width = 400;
if ($switches =~ /s/) {
$width = 200;
}
if ($switches =~ /m/) {
$width = 100;
}
if ($switches =~ /L/) {
$width = "100%";
} else {
$width .= "px";
}
$file =~ s~^//~/~;

if ($file =~ s~^(.*)file=~~) {
$file = ONO::Lib::Web::ToolBox->gen_tmp_access_file("audio",$file);
}

my $AUDIO = qq~<audio id="$id" src="$file" type="$MIME" controls="controls"$MORE style="width:$width"></audio>~;

if ($switches =~ /n/) {
my $NAME = $file;
$NAME =~ s~^(.*)/~~;
if ($switches =~ /N/) {
$NAME =~ s~^(.*?)-~~;
}
if ($switches =~ /X/) {
$NAME =~ s~\.mp3$~~;
}
if ($switches =~ /U/) {
$NAME = ucfirst $NAME;
}
if ($switches =~ /I/) {
my $CTRL;
if ($script_url && $ctrl && $switches =~ /C/) {
my ($LOAD,$SAVE,$DELETE);
if ($ctrl =~ /l/) {
}
if ($ctrl =~ /s/) {
if ($BLK{'save'}) {
$SAVE = qq~<div id="ono_audio_ctrl_save_$file" class="button_green button_mini abs hide" style="top:0px;right:-4px">$BLK{'save'}</div>~;
}
$SAVE = qq~<div class="rel mr5 mt5" onmouseover="onojs_block('ono_audio_ctrl_save_$file');" onmouseout="onojs_hide('ono_audio_ctrl_save_$file');">
<a href="$script_url=save"><img class="block20" src="/ono/osr/images/icons/ono/32x32/start.png" alt="">$SAVE</a>
</div>
~;
}
if ($ctrl =~ /d/) {
if ($BLK{'delete'}) {
$DELETE = qq~<div id="ono_audio_ctrl_del_$file" class="button_red button_mini abs hide" style="top:0px;right:-4px">$BLK{'delete'}</div>~;
}
$DELETE = qq~<div class="rel mr5 mt5" onmouseover="onojs_block('ono_audio_ctrl_del_$file');" onmouseout="onojs_hide('ono_audio_ctrl_del_$file');">
<a href="$script_url=delete"><img class="block20" src="/ono/osr/images/icons/ono/32x32/delete.png" alt="">$DELETE</a>
</div>
~;
}
$CTRL = qq~<td>$LOAD$SAVE$DELETE</td>~;
}
$AUDIO = qq~<table class="default_table">
<tr class="vtop">
<td><img class="block48 mt5" src="/ono/osr/images/icons/crystal/64x64/mimetypes/sound.png" alt=""></td>
<td><div class="ml10 mr10">$NAME</div>$AUDIO</td>
$CTRL
</tr>
</table>
~;
} else {
$AUDIO = qq~<div class="pad10_2">$NAME</div>$AUDIO~;
}
}

if ($switches =~ /b/) {
$AUDIO = qq~<div class="box_darkblack p2">$AUDIO</div>~;
}
if ($switches =~ /B/) {
$AUDIO = qq~<div class="box_darkblack p2" style="background-color:#222222">$AUDIO</div>~;
}

return qq~$AUDIO<script>\$('audio,video').mediaelementplayer();</script>~;

}

sub player_popup {

my (
$self,
$id,
$file,
) = @_;

#: Audio player popup feature.

$file =~ s~^//~/~;
my $MIME = &mime("",$file);

return qq~<div class="rel" style="width:28px;height:31px">
<div id="$id" class="radius5 abs" style="width:28px;overflow:hidden;background-color:#222222;z-index:9"
onmouseover = "document.getElementById('$id').style.width='400px';"
onmouseout = "document.getElementById('$id').style.width='28px';">
<audio id="player2" src="$file" type="$MIME" controls="controls" style="width:400px"></audio>
</div>
</div>
<script>\$('audio,video').mediaelementplayer();</script>
~;

}

sub player_script {

#: Embed the ONO Audio Player JS scripts.
#:
#: -S no script / event listener

my $SCRIPT;

if ($_[1] !~ /S/) {
$SCRIPT = qq~<script>
document.addEventListener('play', function(e){
var audios = document.getElementsByTagName('audio');
for(var idx = 0, len = audios.length; idx < len;idx++){if(audios[idx] != e.target){audios[idx].pause();}}
}, true);
</script>
~;
}

return qq~<script src="/ono/osr/javascript/mediaelement/build/jquery.js"></script>
<script src="/ono/osr/javascript/mediaelement/build/mediaelement-and-player.min.js"></script>
<link rel="stylesheet" href="/ono/osr/javascript/mediaelement/build/mediaelementplayer.min.css" />
$SCRIPT
~;

}

sub mime {

#: Return MIME code.

my $MIME = "audio/mp3";

if ($_[1] =~ /\.m4a$/i) {
$MIME = "audio/mp4";
}
if ($_[1] =~ /\.wav$/i) {
$MIME = "audio/wav";
}
if ($_[1] =~ /\.flac$/i) {
$MIME = "audio/flac";
}

return $MIME;

}

###############################################################################
# end of script
###############################################################################

1;

__END__