当年话下
BASS_ChannelGetLength可以用和BASS_ChannelGetPosition功能解决问题。这是代码:// +build windowspackage mainimport ( "fmt" "syscall" "time" "unsafe")/*基于 [bass.dll](http://us2.un4seen.com/files/bass24.zip)和 [Golang syscall](https://github.com/golang/go/wiki/WindowsDLLs)实现的命令行版播放器。*/type ( BASSErrorGetCode int32)const ( BassUnicode uint32 = 0x80000000 // BASS_UNICODE BassSampleFloat uint32 = 256 // BASS_SAMPLE_FLOAT BassPosByte uint64 = 0 // BASS_POS_BYTE)type BassLib struct { libBass syscall.Handle init uintptr free uintptr streamCreateFile uintptr channelPlay uintptr channelPause uintptr channelStop uintptr channelGetLength uintptr channelGetPosition uintptr channelBytes2Seconds uintptr}func (bass *BassLib) LoadBass(bassDllPath string) bool { bass.libBass, _ = syscall.LoadLibrary(bassDllPath) if bass.libBass == 0 { fmt.Println("Load `bass.dll` library failed!") errCode := bass.GetBassErrorGetCode() fmt.Println("Bass_Init failed!") fmt.Println(errCode) return false } bass.init, _ = syscall.GetProcAddress(bass.libBass, "BASS_Init") // BASS_Init(device, freq, flags, win, clsid) // see http://www.un4seen.com/doc/#bass/BASS_Init.html device := 1 r, _, _ := syscall.Syscall6(bass.init, 5, uintptr(device), uintptr(44100), uintptr(0), uintptr(0), uintptr(0), 0) // var ret = *(* int)(unsafe.Pointer(&r)) if r == 0 { errCode := bass.GetBassErrorGetCode() fmt.Println("Bass_Init failed!") fmt.Println(errCode) return false } return true}func StrPtr(s string) uintptr { p, _ := syscall.UTF16PtrFromString(s) return uintptr(unsafe.Pointer(p))}func (bass *BassLib) PlayFile(filePath string) { bass.streamCreateFile, _ = syscall.GetProcAddress(bass.libBass, "BASS_StreamCreateFile") // hStream = BASS_StreamCreateFile(mem=0, &file, offset=0, length=0, flags=(A_IsUnicode ? 0x80000000 : 0x40000)) // see http://www.un4seen.com/doc/#bass/BASS_StreamCreateFile.html hStream, _, _ := syscall.Syscall6(bass.streamCreateFile, 5, uintptr(0), StrPtr(filePath), uintptr(0), uintptr(0), uintptr(BassUnicode|BassSampleFloat), 0) bass.channelPlay, _ = syscall.GetProcAddress(bass.libBass, "BASS_ChannelPlay") // BASS_ChannelPlay(hStream) // see http://www.un4seen.com/doc/#bass/BASS_ChannelPlay.html r, _, _ := syscall.Syscall(bass.channelPlay, 2, hStream, uintptr(0), 0) if r == 1 { totalDuration := bass.GetAudioByteLength(hStream) // currentPos := bass.GetAudioCurrentBytePosition(hStream) fmt.Println(totalDuration) // fmt.Println(currentPos) time.Sleep(time.Second*1) for { currentPos := bass.GetAudioCurrentBytePosition(hStream) if currentPos >= totalDuration { break } } } else { errCode := bass.GetBassErrorGetCode() fmt.Println("Bass_ChannelPlay failed!") fmt.Println(errCode) }}func (bass *BassLib) GetBassErrorGetCode() BASSErrorGetCode { bassErrorGetCode, _ := syscall.GetProcAddress(bass.libBass, "BASS_ErrorGetCode") // BASS_ErrorGetCode() // BASS_OK BASSErrorGetCode = 0 // all is OK // BASS_ERROR_MEM BASSErrorGetCode = 1 // memory error // ... // see http://www.un4seen.com/doc/#bass/BASS_ErrorGetCode.html errCode, _, _ := syscall.Syscall(bassErrorGetCode, 0, 0, 0, 0) var iErrCode = *(*BASSErrorGetCode)(unsafe.Pointer(&errCode)) return iErrCode}func (bass *BassLib) GetAudioByteLength(handle uintptr) uintptr { // (QWORD) BASS_ChannelGetLength(handle=hStream, mode) // see http://www.un4seen.com/doc/#bass/BASS_ChannelGetLength.html bass.channelGetLength, _ = syscall.GetProcAddress(bass.libBass, "BASS_ChannelGetLength") len, _, _ := syscall.Syscall(bass.channelGetLength, 2, handle, uintptr(BassPosByte), 0) return len}func (bass *BassLib) GetAudioCurrentBytePosition(handle uintptr) uintptr { // BASS_ChannelGetPosition(handle=hStream, mode) // see http://www.un4seen.com/doc/#bass/BASS_ChannelGetPosition.html bass.channelGetPosition, _ = syscall.GetProcAddress(bass.libBass, "BASS_ChannelGetPosition") pos, _, _ := syscall.Syscall(bass.channelGetPosition, 2, handle, uintptr(BassPosByte), 0) return pos}func (bass *BassLib) GetChannelBytes2Seconds(handle uintptr, pos uintptr) uintptr { // BASS_ChannelBytes2Seconds(handle=hStream, pos) // see http://www.un4seen.com/doc/#bass/BASS_ChannelBytes2Seconds.html // bass.channelBytes2Seconds, _ = syscall.GetProcAddress(bass.libBass, "BASS_ChannelBytes2Seconds") len, _, _ := syscall.Syscall(bass.channelBytes2Seconds, 2, handle, pos, 0) return len}func (bass *BassLib) UnLoad() { if bass.libBass != 0 { bass.free, _ = syscall.GetProcAddress(bass.libBass, "BASS_Free") syscall.Syscall(bass.free, 0, 0, 0, 0) // BASS_Free() // see http://www.un4seen.com/doc/#bass/BASS_Free.html syscall.FreeLibrary(bass.libBass) }}func main() { bass := &BassLib{} bass.LoadBass("C:\\workspace\\play\\bass.dll") bass.PlayFile("C:\\workspace\\play\\sample.mp3") bass.UnLoad()}您也可以访问https://gist.github.com/ycrao/e7d1df181f870091b4a6d298d6ea2770#file-bass_play-go-L81-L91。