jballi
Joined: 01 Oct 2005 Posts: 748 Location: Texas, USA
|
Posted: Sat Sep 03, 2011 5:10 am Post subject: |
|
|
skwire was kind enough to point me to this thread. I completely missed it when it was first published (March 2010).
The BASS library published by k3ph (link: here) is significantly more robust that this library but it is very complex and I imagine that a lot people never bothered to play with it because it is overwhelming. The library also uses a very large number of global variables.
The toralf version of the BASS library (this thread) is a significantly scaled down version of k3ph's BASS library but it appears to do most of the stuff that a developer needs to create a basic media player.
There are no examples for this library so I created a couple while learning how to use this library. I'm sharing just in case anyone else can benefit from them.
Requirements: These examples need the bass.ahk and the bass.dll files. See the first post in this thread for links to these files.
Standard Example:
| Code: | #NoEnv
#SingleInstance Force
OnExit Exit
;-- Initialize
BASS_ACTIVE_STOPPED :=0
BASS_ACTIVE_PLAYING :=1
BASS_ACTIVE_STALLED :=2 ;-- Playback of the stream has been stalled due to a lack of sample data. The playback will automatically resume once there is sufficient data to do so.
BASS_ACTIVE_PAUSED :=3
BASS_Load()
hStream:=""
;-- Build GUI
gui Margin,0,0
gui Add,Button,w70 h40,Open
gui Add,Button,x+0 wp hp,Play
gui Add,Button,x+0 wp hp,Pause
gui Add,Button,x+0 wp hp,Stop
gui,Add,Button,x+0 wp hp,Rev10
gui,Add,Button,x+0 wp hp,Middle
gui,Add,Button,x+0 wp hp,Fwd10
gui Show
gosub ButtonOpen
return
GUIEscape:
GUIClose:
if hStream
hStream:=BASS_Stop()
ExitApp
ButtonOpen:
if hStream
hStream:=BASS_Stop()
if not DefaultFolder
DefaultFolder:=A_MyDocuments
gui +OwnDialogs
FileSelectFile MediaFile,1,%DefaultFolder%,Choose a media file
if (MediaFile="")
return
SplitPath MediaFile,,DefaultFolder
gosub ButtonPlay
return
ButtonPlay:
if not hStream
hStream:=BASS_Play(MediaFile)
else
{
Status:=BASS_IsPlaying(hStream)
if (Status=BASS_ACTIVE_PLAYING)
BASS_SetPos(hStream,0)
else
if (Status=BASS_ACTIVE_PAUSED)
BASS_Pause()
else ;-- Everything else
{
hStream:=BASS_Stop() ;-- Necessary if stalled
hStream:=BASS_Play(MediaFile)
}
}
return
ButtonPause:
if hStream
{
Status:=BASS_IsPlaying(hStream)
if Status in %BASS_ACTIVE_PLAYING%,%BASS_ACTIVE_STALLED%,%BASS_ACTIVE_PAUSED%
BASS_Pause()
}
return
ButtonStop:
if hStream
hStream:=BASS_Stop()
return
ButtonFwd10:
if hStream
{
Status:=BASS_IsPlaying(hStream)
if Status in %BASS_ACTIVE_PLAYING%,%BASS_ACTIVE_PAUSED%
{
NewPos:=BASS_Bytes2Seconds(hStream,BASS_GetPos(hStream))+10
MaxPos:=BASS_Bytes2Seconds(hStream,BASS_GetLen(hStream))
if (NewPos>=MaxPos)
NewPos:=MaxPos-0.05
BASS_SetPos(hStream,BASS_Seconds2Bytes(hStream,NewPos))
}
}
return
ButtonMiddle:
if hStream
{
Status:=BASS_IsPlaying(hStream)
if Status in %BASS_ACTIVE_PLAYING%,%BASS_ACTIVE_PAUSED%
{
NewPos:=BASS_Bytes2Seconds(hStream,BASS_GetLen(hStream))/2
BASS_SetPos(hStream,BASS_Seconds2Bytes(hStream,NewPos))
}
}
return
ButtonRev10:
if hStream
{
Status:=BASS_IsPlaying(hStream)
if Status in %BASS_ACTIVE_PLAYING%,%BASS_ACTIVE_PAUSED%
{
NewPos:=BASS_Bytes2Seconds(hStream,BASS_GetPos(hStream))-10
if (NewPos<0)
NewPos:=0
BASS_SetPos(hStream,BASS_Seconds2Bytes(hStream,NewPos))
}
}
return
Exit:
BASS_Free()
ExitApp
#include bass.ahk
|
Playlist Example:
| Code: | #NoEnv
#SingleInstance Force
OnExit Exit
;-- Initialize
BASS_ACTIVE_STOPPED :=0
BASS_ACTIVE_PLAYING :=1
BASS_ACTIVE_STALLED :=2
;-- Playback of the stream has been stalled due to a lack of sample data.
; The playback will automatically resume once there is sufficient data to
; do so.
BASS_ACTIVE_PAUSED :=3
BASS_Load()
hStream:=""
;-- Build GUI
gui Margin,0,0
gui Add,Button,w100 h50 gOpen ,Open
gui Add,Button,x+0 wp hp gPlay ,Play
gui Add,Button,x+0 wp hp gPause,Pause
gui Add,Button,x+0 wp hp vStop gStop ,Stop
gui Add,Button,x+0 wp hp gPrev ,Prev
gui Add,Button,x+0 wp hp gNext ,Next
gui Add
,Progress
,x+0 w10 hp
|| cNavy
|| Range0-32768
|| Vertical
|| vLevelLeft
gui Add
,Progress
,x+0 w10 hp
|| cNavy
|| Range0-32768
|| Vertical
|| vLevelRight
gui Add,Text,xm w40,%A_Space%Pos:
gui Add
,Slider
,x+0 w270
|| +Disabled ;-- Start off disabled
|| ToolTip
|| vPosSlider
|| gPosSlider
gui Add,Text,x+0 w40 hp,%A_Space%Vol:
gui Add
,Slider
,x+0 w270 hp
|| ToolTip
|| vVolSlider
|| gVolSlider
,% BASS_Volume()*100
gui Add
,ListView
,xm w620 r20
|| Count1000
|| -Hdr
|| vPlaylist
|| gPlaylistAction
,Media File Name
gui Show
;-- Start 'R Up
gosub Open
return
GUIEscape:
GUIClose:
gosub Stop
ExitApp
PlaylistAction:
if (A_GuiEvent="DoubleClick")
{
;-- Anything selected? (Seems redundant for a double-click, but it's not)
if LV_GetCount("Selected")
{
PlaylistIndex:=A_EventInfo-1
gosub Next
}
}
return
Open:
;-- Attach messages/dialogs to current GUI
gui +OwnDialogs
;-- Close if anything is open
if hStream
gosub Stop
;-- Initialize
LV_Delete()
if MediaPath is Space
MediaPath:=A_MyDocuments
;-- Browse for it
gui +OwnDialogs
FileSelectFolder
,MediaFolder
,*%MediaPath%
,0
,Add media folder...
;-- Nothing selected?
If ErrorLevel
{
MsgBox 48,Open Failure,No media folder selected.
return
}
MediaPath:=MediaFolder
;[=====================]
;[ Populate playlist ]
;[=====================]
;-- Redraw off
GUIControl -Redraw,Playlist
;-- Find media files
$BatchLines:=A_BatchLines
SetBatchLines 50ms
Loop %MediaFolder%\*.*,,1
if A_LoopFileExt in mp3,wav ;-- Add more extensions if desired
LV_Add("",A_LoopFileLongPath)
SetBatchLines %$BatchLines%
;-- Redraw on
GUIControl +Redraw,Playlist
;-- Anything loaded
if LV_GetCount()=0
{
MsgBox 48,Open Failure,No media files found.
return
}
;-- Get it started
PlaylistIndex:=0
gosub Next
return
Play:
if not hStream
hStream:=BASS_Play(MediaFile)
else
{
Status:=BASS_IsPlaying(hStream)
if (Status=BASS_ACTIVE_PLAYING)
BASS_SetPos(hStream,0)
else
if (Status=BASS_ACTIVE_PAUSED)
BASS_Pause()
else ;-- Everything else
{
hStream:=BASS_Stop() ;-- Necessary if stalled
hStream:=BASS_Play(MediaFile)
}
}
;-- Start/Restart timers
SetTimer NotifyEOP,250
GUIControl Enable,PosSlider
SetTimer UpdatePosSlider,250
SetTimer UpdateLevel,50
return
Pause:
if hStream
{
Status:=BASS_IsPlaying(hStream)
if Status in %BASS_ACTIVE_PLAYING%,%BASS_ACTIVE_STALLED%,%BASS_ACTIVE_PAUSED%
BASS_Pause()
}
return
Stop:
if hStream
hStream:=BASS_Stop()
;-- NotifyEOF
SetTimer NotifyEOP,Off
;-- Position
SetTimer UpdatePosSlider,Off
GUIControl,,PosSlider,0
GUIControl Disable,PosSlider
;-- Level
SetTimer UpdateLevel,Off
GUIControl,,LevelLeft,0
GUIControl,,LevelRight,0
return
Prev:
if (PlaylistIndex>1)
{
PlaylistIndex-=2
gosub Next
}
return
Next:
Sleep 0 ;-- (Helps to) keep this thread from stepping on itself
if hStream
gosub Stop
;-- At the end?
if (PlaylistIndex>=LV_GetCount())
return
;-- Increment index
PlayListIndex++
;-- UnSelect all, select new item
LV_Modify(0,"-Select")
LV_Modify(PlaylistIndex,"+Select +Focus +Vis")
;-- Collect media file name
LV_GetText(MediaFile,PlaylistIndex,1)
;-- Play it
gosub Play
;-- This command will open the file and establish a stream
;-- Collect length (in seconds)
MediaLength:=BASS_Bytes2Seconds(hStream,BASS_GetLen(hStream))
;-- The length of the media file is collected once on open/play. The value
; is used by the PosSlider routine.
return
PosSlider:
if hStream
{
Status:=BASS_IsPlaying(hStream)
if Status in %BASS_ACTIVE_PLAYING%,%BASS_ACTIVE_PAUSED%
{
if (PosSlider=100) ;-- Moved to the very end (BASS doesn't respond to this)
Pos:=BASS_GetLen(hStream)-1024 ;-- This usually works. Need to determine if it the best solution.
else
Pos:=BASS_Seconds2Bytes(hStream,MediaLength*(PosSlider/100))
BASS_SetPos(hStream,Pos)
}
;-- Reset focus (anything but the PosSlider)
GUIControl Focus,Stop
}
return
UpdatePosSlider:
if hStream
{
Status:=BASS_IsPlaying(hStream)
if Status in %BASS_ACTIVE_PLAYING%,%BASS_ACTIVE_PAUSED%
{
;-- Only update PosSlider if object is NOT in focus
GUIControlGet Control,FocusV
if (Control<>"PosSlider")
GUIControl,,PosSlider,% (BASS_Bytes2Seconds(hStream,BASS_GetPos(hStream))/MediaLength)*100
}
}
return
UpdateLevel:
if hStream
{
if (BASS_IsPlaying(hStream)=BASS_ACTIVE_PLAYING)
{
BASS_GetLevel(hStream,LevelLeft,LevelRight)
GUIControl,,LevelLeft,%LevelLeft%
GUIControl,,LevelRight,%LevelRight%
}
else
{
GUIControl,,LevelLeft,0
GUIControl,,LevelRight,0
}
}
return
VolSlider:
Bass_Volume(VolSlider/100)
;-- Reset focus (anything but the VolSlider)
GUIControl Focus,Stop
return
NotifyEOP:
if hStream
if (BASS_IsPlaying(hStream)=BASS_ACTIVE_STOPPED)
gosub Next
return
Exit:
BASS_Free()
ExitApp
#include bass.ahk
|
Although these examples are AutoHotkey_L ready (I only tested using the Unicode version), they won't work on the most recent versions of AuthoHotkey_L because this BASS library is not AutoHotkey_L and/or Unicode ready. If anyone is interested in a tweaked-for-unicode version, PM me and I'll send you what I have. There are only minor changes to the current library but I haven't done any significant testing on it so it's not forum ready.
Edit: Updated the Playlist example to include progress bars for the left and right channels. |
|