antosdk-apps/MediaPlayer/coffees/main.coffee
2018-04-14 15:52:19 +00:00

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