mirror of
https://github.com/antos-rde/antosdk-apps.git
synced 2024-12-25 11:48:21 +01:00
262 lines
9.8 KiB
CoffeeScript
262 lines
9.8 KiB
CoffeeScript
class MediaPlayer extends this.OS.GUI.BaseApplication
|
|
constructor: ( args ) ->
|
|
super "MediaPlayer", args
|
|
|
|
main: () ->
|
|
me = @
|
|
@volsw = @find "play-vol"
|
|
@volctl = @find "vol-control"
|
|
@volsw.set "swon", true
|
|
@volctl.set "onchange", (v) ->
|
|
return unless (me.volsw.get "swon")
|
|
Howler.volume (me.volctl.get "value")/100
|
|
@volctl.set "value", 70
|
|
@playlist = @find "playlist"
|
|
@playtime = @find "play-time"
|
|
@songname = @find "song-name"
|
|
@totaltime = @find "total-time"
|
|
@playpause = @find "play-pause"
|
|
@progress = @find "play-slide"
|
|
@playran = @find "play-random"
|
|
@history = []
|
|
@currsong = undefined
|
|
@timer = undefined
|
|
@animator = @find "animation"
|
|
|
|
@volsw.set "onchange", (e) ->
|
|
return Howler.volume 0 if not e.data
|
|
Howler.volume (me.volctl.get "value")/100
|
|
@playlist.set "buttons", [
|
|
{
|
|
text: "+",
|
|
onbtclick: () ->
|
|
me.openDialog "FileDiaLog", (d,n,p,f) ->
|
|
return me.scanDir f if f.type is "dir"
|
|
f.text = f.filename
|
|
f.iconclass = "fa fa-music"
|
|
me.playlist.push f, true
|
|
, "__(Select MP3 file or a folder)"
|
|
, { mimes: ["dir", "audio/mpeg"] }
|
|
},
|
|
{
|
|
text: "-",
|
|
onbtclick: () ->
|
|
sel = me.playlist.get "selected"
|
|
return unless sel
|
|
me.stop() if sel is me.currsong
|
|
me.playlist.remove sel, true
|
|
},
|
|
{
|
|
text: "",
|
|
onbtclick: () ->
|
|
me.openDialog "PromptDialog", (link) ->
|
|
return unless link and link isnt ""
|
|
data = {
|
|
text: link,
|
|
path: link,
|
|
iconclass: "fa fa-link",
|
|
broadcast: true
|
|
}
|
|
me.playlist.push data, true
|
|
, "__(MP3 Radio broadcast)", { label:"Enter radio broadcast link" }
|
|
, iconclass: "fa fa-link"
|
|
},
|
|
{
|
|
text:"",
|
|
iconclass: "fa fa-save",
|
|
onbtclick: () ->
|
|
playlist = []
|
|
for v in me.playlist.get "items"
|
|
playlist.push {
|
|
text: v.text,
|
|
path: v.path,
|
|
iconclass: v.iconclass,
|
|
broadcast: if v.broadcast then v.broadcast else false
|
|
}
|
|
fp = "Untitled".asFileHandler()
|
|
me.openDialog "FileDiaLog", (d,n,p,f) ->
|
|
fp = "#{d}/#{n}".asFileHandler()
|
|
fp.cache = playlist
|
|
fp.write "object", (r) ->
|
|
return me.error __("Cannot save playlist: {0}", r.error) if r.error
|
|
me.notify __("Playlist saved")
|
|
, "__(Save Playlist)", { file: fp }
|
|
},
|
|
{
|
|
text:"",
|
|
iconclass: "fa fa-folder",
|
|
onbtclick: () ->
|
|
me.openDialog "FileDiaLog", (d,n,p,f) ->
|
|
f.path.asFileHandler().read (d) ->
|
|
me.stop()
|
|
me.playlist.set "items", d
|
|
, "json"
|
|
, "__(Open Playlist)", { mimes: ["application/json"] }
|
|
}
|
|
]
|
|
@playlist.set "onlistdbclick", (e) ->
|
|
return unless e
|
|
e.data.index = e.idx
|
|
me.play e.data
|
|
@progress.set "onchange", (s) ->
|
|
me.seek s
|
|
@playpause.set "onchange", (e) ->
|
|
me.togglePlayPause()
|
|
(@find "play-prev").set "onbtclick", () ->
|
|
me.prevSong()
|
|
(@find "play-next").set "onbtclick", () ->
|
|
me.nextSong()
|
|
$(@animator).css("visibility", "hidden")
|
|
scanDir: (f) ->
|
|
me = @
|
|
f.path.asFileHandler().read (d) ->
|
|
return me.error __("Unable to read {0}", d.error) if d.error
|
|
for v in d.result when v.mime.match /audio\/mpeg/
|
|
v.iconclass = "fa fa-music"
|
|
v.text = v.filename
|
|
me.playlist.push v, true
|
|
|
|
|
|
togglePlayPause: () ->
|
|
return @playpause.set "swon",false unless @currsong and @currsong.howl
|
|
sound = @currsong.howl
|
|
if sound.playing()
|
|
sound.pause()
|
|
else
|
|
sound.play()
|
|
|
|
nextSong: () ->
|
|
idx = -1
|
|
if (@playran.get "swon")
|
|
idx = @randomSong()
|
|
else
|
|
len = (@playlist.get "items").length
|
|
if len > 0
|
|
idx = 0
|
|
idx = @currsong.index + 1 if @currsong
|
|
idx = 0 if idx >= len
|
|
return if idx is -1
|
|
@history.pop() if history.length >= 10
|
|
@history.unshift @currsong.index if @currsong
|
|
@playlist.set "selected", idx
|
|
sel = @playlist.get "selected"
|
|
sel.index = idx
|
|
@play sel
|
|
|
|
prevSong: () ->
|
|
idx = -1
|
|
if (@playran.get "swon")
|
|
idx = @history.shift() if @history.length > 0
|
|
else
|
|
len = (@playlist.get "items").length
|
|
if len > 0
|
|
idx = @currsong.index - 1 if @currsong
|
|
idx = 0 if idx < 0
|
|
return if idx is -1
|
|
@playlist.set "selected", idx
|
|
sel = @playlist.get "selected"
|
|
sel.index = idx
|
|
@play sel
|
|
|
|
randomSong: () ->
|
|
len = (@playlist.get "items").length
|
|
return -1 unless len > 0
|
|
return Math.floor(Math.random() * Math.floor(len))
|
|
|
|
play: (file) ->
|
|
me = @
|
|
@stop()
|
|
@currsong = file
|
|
sound = file.howl
|
|
if not sound
|
|
sound = file.howl = new Howl {
|
|
src: [
|
|
file.path.asFileHandler().getlink()
|
|
],
|
|
preload:true,
|
|
buffer: true,
|
|
html5: true, # Force to HTML5 so that the audio can stream in (best for large files).
|
|
format: ['mp3', 'aac'],
|
|
onplay: () ->
|
|
$(me.animator).css("visibility", "visible")
|
|
#Display the duration.
|
|
me.playpause.set "swon", true
|
|
console.log "play"
|
|
me.songname.set "text", file.text
|
|
duration = Math.round(sound.duration())
|
|
if duration isnt Infinity
|
|
me.totaltime.set "text", me.formatDuration duration
|
|
me.progress.set "max", duration
|
|
else
|
|
me.totaltime.set "text", "--:--"
|
|
me.progress.set "max", 0
|
|
if not file.broadcast
|
|
func = () ->
|
|
if sound.playing()
|
|
seek = Math.round(sound.seek()) || 0
|
|
me.progress.set "value", seek
|
|
me.playtime.set "text", me.formatDuration seek
|
|
me.timer = setTimeout (() -> func()), 1000
|
|
func()
|
|
else
|
|
me.totaltime.set "text", "--:--"
|
|
me.progress.set "value", (me.progress.get "max")
|
|
func = () ->
|
|
if sound.playing()
|
|
seek = Math.round(sound.seek()) || 0
|
|
me.playtime.set "text", me.formatDuration seek
|
|
me.timer = setTimeout (() -> func()), 1000
|
|
func()
|
|
onload: () ->
|
|
# Start the wave animation.
|
|
console.log "load"
|
|
$(me.animator).css("visibility", "hidden")
|
|
sound.play() if not file.broadcast
|
|
|
|
onend: () ->
|
|
# Stop the wave animation.
|
|
me.progress.set "value", 0
|
|
clearTimeout me.timer if me.timer
|
|
me.playpause.set "swon", false
|
|
$(me.animator).css("visibility", "hidden")
|
|
me.nextSong()
|
|
onpause: ()->
|
|
# Stop the wave animation.
|
|
console.log "pause"
|
|
clearTimeout me.timer if me.timer
|
|
me.playpause.set "swon", false
|
|
$(me.animator).css("visibility", "hidden")
|
|
|
|
onstop: () ->
|
|
me.progress.set "value", 0
|
|
clearTimeout me.timer if me.timer
|
|
me.playpause.set "swon", false
|
|
$(me.animator).css("visibility", "hidden")
|
|
console.log "stop"
|
|
}
|
|
sound.play() if file.broadcast
|
|
else
|
|
sound.play()
|
|
$(@animator).css("visibility", "visible")
|
|
stop: () ->
|
|
if @currsong and @currsong.howl
|
|
@currsong.howl.stop() if @currsong.howl.playing()
|
|
|
|
seek: (v) ->
|
|
return unless @currsong and @currsong.howl and not @currsong.broadcast
|
|
return unless (@progress.get "max") > 0
|
|
sound = @currsong.howl
|
|
sound.seek(v)
|
|
|
|
formatDuration: (s) ->
|
|
min = Math.floor(s/60)
|
|
sec = s % 60
|
|
min = if min < 10 then "0#{min}" else "#{min}"
|
|
sec = if sec < 10 then "0#{sec}" else "#{sec}"
|
|
"#{min}:#{sec}"
|
|
|
|
cleanup: (evt) ->
|
|
@stop()
|
|
# only one instance is allow
|
|
MediaPlayer.singleton = true
|
|
this.OS.register "MediaPlayer", MediaPlayer |