Media player

By Aion- on Dec 29, 2012

A long time ago I started working on a media player for mIRC, but I never got the chance to finish it up until now. It is a fairly simple dialog and uses the file handling commands for faster operations.

I haven't found any bugs other than mIRC being unable to play certain songs which is, apparently, caused by bad ID3 tags.

I doubt I will ever expand this snippet so I decided to post it. Just load it into your script editor and right-click anywhere in your status, channel or query window to open it.

menu status,channel,query {
  Aion's media player: dialog $+(-, $iif($dialog(MediaPlayer), ev, md)) MediaPlayer MediaPlayer
}

dialog MediaPlayer {
  title "Aion's media player"
  size -1 -1 173 139
  option dbu
  box "Songs", 1, 2 2 75 135
  list 2, 4 10 70 113, size hsbar vsbar extsel
  text "", 3, 81 10 88 8, center
  scroll "", 4, 82 34 86 8, range 0 100 horizontal
  button "Shuffle", 5, 4 124 25 11
  box "Controls", 7, 79 49 92 46
  button "Previous", 8, 81 57 27 12
  button "Play", 10, 111 57 27 12
  button "Next", 9, 141 57 27 12
  box "Volume: 100%", 11, 82 72 62 20
  scroll "", 12, 86 80 54 8, range 0 100 horizontal
  box "Mute", 13, 147 72 21 20
  check "", 14, 154 79 8 10
  box "Playing", 15, 79 2 92 19
  box "Position", 16, 79 25 92 20
  box "Files", 17, 79 97 92 40
  button "Add folder", 18, 82 105 37 12
  button "Add files", 19, 82 121 37 12
  button "Remove all", 20, 130 105 37 12
  button "Remove file", 21, 130 121 37 12
  combo 6, 30 124 44 50, size drop
}

; Initializations
on *:dialog:MediaPlayer:init:0:{
  didtok $dname 6 32 Continuous Random Repeat
  did -c $dname 6 1
  did -c $dname 12 100
  loadMediaFiles
}

; Plays the double-clicked item
on *:dialog:MediaPlayer:dclick:2:{
  if ($did($dname, 2).sel) {
    playSong $did($dname, 2).seltext
  }
}

; Seeks the song to the specified position defined by the scrolling event
on *:dialog:MediaPlayer:scroll:4:{
  if ($insong) {
    if (!$timer(MediaPlayerScrollbarAnimation).pause) {
      .timerMediaPlayer.animation.scrollbar -p
    }
    var %seekPosition $did($dname, $did).sel
    var %length $mp3($insong.fname).length
    ; Fractional numbers do not work when seeking to a position
    splay -p seek $int($calc(%length * %seekPosition / 100))
    .timerMediaPlayer.animation.scrollbar -r
  }
}

; Adjusts the volume accordingly
on *:dialog:MediaPlayer:scroll:12:{
  var %value $did($dname, $did).sel
  did -ar $dname 11 Volume: %value $+ %
  var %volume $calc(%value * 655.35)
  vol -v %volume
}

; Handles mute setting
on *:dialog:MediaPlayer:sclick:14:{
  vol $+(-vu, $iif($did($dname, $did).state == 0, 2, 1))
}

; Plays either the next or previous song
on *:dialog:MediaPlayer:sclick:8,9:{
  if (!$did($dname, 2).sel) {
    if ($insong) {
      did -c $dname 2 $didwm($dname, 2, $+(*, $mid($nopath($insong.fname), 0, -4), *))
    }
    else {
      did -c $dname 2 1
    }
  }
  var %button $did($dname, $did).text
  var %index -1
  if (%button == next) {
    var %sel $did($dname, 2).sel
    if (%sel == $did($dname, 2).lines) {
      %sel = 0
    }
    inc %sel
    %index = %sel
  }
  else {
    var %sel $did($dname, 2).sel
    if ($did($dname, 2, 0).sel > 1) {
      %sel = $calc(%sel + $v1 - 1)
    }
    if (%sel == 1) {
      %sel = $calc($did($dname, 2).lines + 1)
    }
    dec %sel
    %index = %sel
  }
  did -c $dname 2 %index
  playSong $did($dname, 2).seltext
}

; Plays, pauses or resumes a song
on *:dialog:MediaPlayer:sclick:10:{
  var %button $did($dname, $did).text
  if (%button == Pause) {
    if ($insong) {
      splay -p pause
      did -ar $dname $did Resume
      .timerMediaPlayer.animation.label -p
    }
  }
  elseif (%button == Resume) {
    if ($insong.pause) {
      splay -p resume
      .timerMediaPlayer.animation.label -r
    }
    did -ar $dname $did $iif($insong, Pause, Play)
  }
  else {
    if (!$did($dname, 2).sel) {
      did -c $dname 2 1
    }
    playSong $did($dname, 2).seltext
  }
}

; Shuffles the media files
on *:dialog:MediaPlayer:sclick:5:{
  if ($exists($getMediaFile())) {
    shuffle
    loadMediaFiles
    if ($insong) {
      var %index $didwm($dname, 2, $+(*, $mid($nopath($insong.fname), 0, -4), *))
      did -c $dname 2 %index
    }
  }
}

; Adds files
on *:dialog:MediaPlayer:sclick:18,19:{
  var %length 0
  var %music $iif($did == 18, $sdir($getMusicLib()), $null)
  if (%music) {
    if (!$exists(%music)) {
      noop $tip(MediaPlayer, MediaPlayer, The chosen directory does not exist.)
      return
    }
    %length = $findfile(%music, *.mp3, 0)
  }
  else {
    %length = $msfile($getMusicLib())
  }
  if (%length < 1) {
    !return
  }
  var %index 1
  .fopen $+($iif($exists($getMediaFile()), $null, -n), $chr(32), MediaWriting) $getMediaFile()
  if ($lines($getMediaFile()) > 0) {
    .fseek -l MediaWriting $calc($v1 + 1)
    :error
    reseterror
  }
  while (%index <= %length) {
    var %file $iif(%music, $findfile(%music, *.mp3, %index), $msfile(%index))
    var %extension $right(%file, 3)
    if (%extension == mp3) {
      .fwrite -n MediaWriting %file
    }
    inc %index
  }
  .fclose MediaWriting
  removeDuplicates
  loadMediaFiles
}

; Removes files
on *:dialog:MediaPlayer:sclick:20,21:{
  if ($did == 20) {
    var %mediaFile $getMediaFile()
    if ($exists(%mediaFile)) {
      .remove %mediaFile
    }
    did -r $dname 2
    splay -p stop
  }
  else {
    if (!$did($dname, 2).sel) {
      return
    }
    .fopen MediaRead $getMediaFile()
    .fopen -o MediaWriting tmpFiles.txt
    var %sel $did($dname, 2).sel
    var %index 1
    var %length $lines($getMediaFile())
    while (%index <= %length) {
      if (%index != %sel) {
        .fseek -l MediaRead %index
        var %file $fread(MediaRead)
        if (%file) {
          .fwrite -n MediaWriting %file
        }
      }
      inc %index
    }
    .fclose MediaRead
    .fclose MediaWriting
    .remove $getMediaFile()
    .rename tmpFiles.txt $getMediaFile()
    loadMediaFiles
  }
}

; Cleans up
on *:dialog:MediaPlayer:close:0:{
  if ($insong) {
    splay -p stop
  }
  .timerMediaPlayer.* off
  vol -vpu2 65535
}

on *:mp3end:{
  var %playMode $did(MediaPlayer, 6).text
  var %song $filename
  var %index $didwm(MediaPlayer, 2, $+(*, $mid($nopath(%song), 0, -4), *))
  if (%playMode == continuous) {
    if (%index == $did(MediaPlayer, 2).lines) {
      %index = 0
    }
    inc %index
  }
  elseif (%playMode == random) {
    var %lines $did(MediaPlayer, 2).lines
    if (%lines > 1) {
      :getNewIndex
      var %newIndex $rand(1, %lines)
      if (%newIndex == %index) {
        goto getNewIndex
      }
      %index = %newIndex
    }
  }
  did -c MediaPlayer 2 %index
  playSong $did(MediaPlayer, 2).seltext
}

; Animates the label on which the current song is displayed
alias -l animateLabel {
  if ($dialog(MediaPlayer)) {
    if ($insong) {
      ; replacing spaces for non-breaking spaces
      var %title $replace($mid($nopath($insong.fname), 0, -4), $chr(32), $chr(160))
      var %titleLength $len(%title)
      if (%titleLength > 40) {
        %title = %title $+ $str($chr(160), $calc((%titleLength - 40) * 2))
      }
      ; replacing 0's for o's to ensure there are no trailing 0's (evaluates to null otherwise)
      var %string $replace($did(MediaPlayer, 3).text, $chr(48), $chr(111))
      if (%string) {
        %titleLength = $len(%title)
        var %stringLength $len(%string)
        if (%stringLength < %titleLength) {
          inc %stringLength
          did -ar MediaPlayer 3 $left(%title, %stringLength)
        }
        else {
          did -ar MediaPlayer 3 $left(%title, 1)
        }
      }
      else {
        did -ar MediaPlayer 3 %title
      }
      return
    }
    else {
      did -ar MediaPlayer 3
    }
  }
  .timerMediaPlayer.animation.label off
}

; Animates the scrollbar position to reflect the position of the current song playing
alias -l animateScrollbar {
  if ($dialog(MediaPlayer)) {
    if ($insong) {
      ; $insong.length returns wrong values in some cases.
      var %length $mp3($insong.fname).length
      var %position $insong.pos
      did -c MediaPlayer 4 $int($calc(%position / %length * 100))
      %position = $calc(%length / 1000 - %position / 1000)
      did -ar MediaPlayer 16 Position - $asctime(%position, nn:ss)
      return
    }
    else {
      did -c MediaPlayer 4 0
      did -ar MediaPlayer 16 Position
    }
  }
  .timerMediaPlayer.animation.scrollbar off
}

; Gets the filename of the given string
alias -l getFile {
  var %mediaFile $getMediaFile()
  if ($exists(%mediaFile)) {
    var %filename $1-
    return $read(%mediaFile, w, $+(*,%filename,.*))
  }
  return $null
}

; Gets the music library. You may optionally change it to your music directory.
alias -l getMusicLib {
  return "C:\"
}

; Gets the media file
alias -l getMediaFile {
  if (!$exists(MediaPlayer)) {
    mkdir MediaPlayer
  }
  return $qt(MediaPlayer\files.txt)
}

; Loads the contents of the media file
alias -l loadMediaFiles {
  var %mediaFile $getMediaFile()
  if ($exists(%mediaFile)) {
    var %length $lines(%mediaFile)
    if (%length < 1) {
      return
    }
    did -r MediaPlayer 2
    var %index 1
    .fopen MediaRead %mediaFile
    while (%index <= %length) {
      .fseek -l MediaRead %index
      var %file $fread(MediaRead)
      if (%file) {
        did -a MediaPlayer 2 $mid($nopath(%file), 0, -4)
      }
      inc %index
    }
    .fclose MediaRead
    did -z MediaPlayer 2
  }
}

; Plays the given song name
alias -l playSong {
  var %song $getFile($1-)
  if (%song) {
    if ($insong) {
      splay -p stop
    }
    .timerMediaPlayer.* off
    splay -p %song
    did -ar MediaPlayer 3 $did(MediaPlayer, 2).seltext
    did -ar MediaPlayer 10 Pause
    animateScrollbar
    .timerMediaPlayer.animation.scrollbar -m 0 1000 animateScrollbar
    .timerMediaPlayer.boot.animation.label 1 4 .timerMediaPlayer.animation.label 0 1 animateLabel
    :error
    if ($error) {
      noop $tip(MediaPlayer, Media Player, An error occurred while attempting to play $qt($1-) $+ . $+ $crlf $error)
      reseterror
    }
  }
  else {
    noop $tip(MediaPlayer, MediaPlayer, Coulnd't play $qt($1-) because it was not found.)
  }
}

; Performs a random permutation of the given elements
alias -l randomPermutation {
  var %length $numtok($1-, 32)
  if (%length < 1) {
    !return $1
  }
  tokenize 32 $1-
  var %elements $1-
  var %index 1
  while (%index < %length) {
    var %newIndex $rand(%index, %length)
    if (%index == %newIndex) {
      continue
    }

    var %token $gettok(%elements, %index, 32)
    var %newToken $gettok(%elements, %newIndex, 32)

    %elements = $remtok(%elements, %token, 1, 32)
    %elements = $remtok(%elements, %newToken, 1, 32)

    %elements = $instok(%elements, %newToken, %index, 32)
    %elements = $instok(%elements, %token, %newIndex, 32)

    inc %index
  }
  return %elements
}

; Removes duplicates
alias -l removeDuplicates {
  var %mediaFile $getMediaFile()
  if ($exists(%mediaFile)) {
    var %lines $lines(%mediaFile)
    if (%lines < 1) {
      return
    }
    .fopen MediaRead %mediaFile
    var %index 1
    var %duplicates
    while (%index <= %lines) {
      .fseek -l MediaRead %index
      var %file $fread(MediaRead)
      if (%file) {
        var %currentIndex %index
        while (%index <= %lines) {
          .fseek -l MediaRead %index
          if (%index > %currentIndex) {
            var %newFile $fread(MediaRead)
            if ($nopath(%newFile) == $nopath(%file)) {
              %duplicates = %duplicates %index
            }
          }
          inc %index
        }
        %index = %currentIndex
      }
      inc %index
    }
    if (!%duplicates) {
      .fclose MediaRead
      return
    }
    .fopen -no MediaWrite MediaPlayer\files.temp
    %index = 1
    while (%index <= %lines) {
      if (!$istok(%duplicates, %index, 32)) {
        .fseek -l MediaRead %index
        var %file $fread(MediaRead)
        if (%file) {
          .fwrite -n MediaWrite %file
        }
      }
      inc %index
    }
    .fclose MediaRead
    .fclose MediaWrite
    .remove %mediaFile
    .rename MediaPlayer\files.temp %mediaFile
  }
}

; Shuffles the media files
alias -l shuffle {
  var %mediaFile $getMediaFile()
  if ($exists(%mediaFile)) {
    var %lines $lines(%mediaFile)
    if (%lines < 1) {
      return
    }
    var %elements $regsubex($str(a, %lines),/./g,\n $+ $chr(32))
    :error
    if ($error) {
      ; If there are ~1050 lines, an error will be thrown
      noop $tip(MediaPlayer, Media Player, An error has occurred while shuffling. $+ $crlf $v1)
      reseterror
      return
    }
    %elements = $randomPermutation(%elements)
    .fopen MediaRead %mediaFile
    .fopen -no MediaWrite MediaPlayer\files.temp
    var %index 1
    while (%index <= %lines) {
      var %line $gettok(%elements, %index, 32)
      .fseek -l MediaRead %line
      var %element $fread(MediaRead)
      if (%element) {
        .fwrite -n MediaWrite %element
      }
      inc %index
    }
    .fclose MediaRead
    .fclose MediaWrite
    .remove %mediaFile
    .rename MediaPlayer\files.temp %mediaFile
  }
}

Comments

Sign in to comment.
ocboyintn   -  Jan 06, 2013

i got the songs uploaded to the player but they dont play..

Aion-  -  Jan 06, 2013

Do you get an error message? It is perfectly fine for me.

Sign in to comment

Are you sure you want to unfollow this person?
Are you sure you want to delete this?
Click "Unsubscribe" to stop receiving notices pertaining to this post.
Click "Subscribe" to resume notices pertaining to this post.