GO语言练习:第二个工程--模拟音乐播放器
1、代码
2、编译及运行
1、目录结构
1.1)
$ tree
.
├── mplayer.go
└── src
├── mlib
│ ├── manager.go
│ └── manager_test.go
└── mp
├── mp3.go
└── play.go
1.2)mlib库的代码
1.2.1)manager.go代码
package library
import "errors"
type MusicEntry struct {
Id string
Name string
Artist string
Genre string
Source string
Type string
}
type MusicManager struct {
musics []MusicEntry
}
func NewMusicManager() * MusicManager {
return &MusicManager {make( []MusicEntry, 0)}
}
func (m * MusicManager) Len() int {
return len(m.musics);
}
func (m* MusicManager ) Get(index int) (music * MusicEntry, err error) {
if index < 0 || index >= len(m.musics) {
return nil, errors.New("Index out of range.")
}
return &m.musics[index], nil
}
func (m * MusicManager) Find (name string) * MusicEntry {
if len(m.musics) == 0 {
return nil
}
for _,m := range m.musics {
if m.Name == name {
return &m
}
}
return nil
}
func (m * MusicManager) Add (music * MusicEntry) {
m.musics = append(m.musics, * music)
}
func (m * MusicManager) Remove (index int) * MusicEntry {
if index < 0 || index >= len(m.musics) {
return nil
}
removedMusic := &m.musics[index]
if index < len(m.musics) - 1 {
m.musics = append(m.musics[:index - 1], m.musics[index + 1:]...)
}else if index == 0 {
m.musics = make([]MusicEntry, 0)
} else {
m.musics = m.musics[:index - 1]
}
return removedMusic
}
func (m * MusicManager) RemoveByName (name string) * MusicEntry {
var removedMusic * MusicEntry = nil
var iPos int = -1
for i := 0; i < m.Len(); i++ {
if m.musics[i].Name == name {
iPos = i
break
}
}
if iPos < 0 {
return nil
}
removedMusic = m.Remove(iPos)
return removedMusic
}
1.2.2)manager.go的测试代码manager_test.go
package library import (
"testing"
) func TestOps(t * testing.T) {
mm := NewMusicManager()
if mm == nil {
t.Error("NewMusicManager faild.");
}
if mm.Len() != 0 {
t.Error("NewMusicManager faild, not empty")
}
m0 := &MusicEntry { "1", "My Heart Will Go On", "Celion Dion", "Pop", "http://qbox.me/24501234", "MP3" }
mm.Add(m0) if mm.Len() != 1 {
t.Error("MusicManager.Add faild.")
} m := mm.Find(m0.Name)
if m == nil {
t.Error("MusicManager.Find faild")
} if m.Id != m0.Id ||
m.Name != m0.Name ||
m.Artist != m0.Artist ||
m.Genre != m0.Genre ||
m.Source != m0.Source ||
m.Type != m0.Type {
t.Error("MusicManager.Find() faild. Found item mismatch.")
} m, err := mm.Get(0)
if m == nil {
t.Error("MusicManager.Get() faild.", err)
} m = mm.Remove(0)
if m == nil || mm.Len() != 0 {
t.Error("MusicManager.Remove() faild.", err)
}
}
1.3)mp库代码
1.3.1)src/mp/mp3.go代码
package mp import (
"fmt"
"time"
) type MP3Player struct {
stat int
progress int
} type WAVPlayer struct {
stat int
progress int
} func (p * MP3Player) Play (source string) {
fmt.Println("Playing MP3 music", source) p.progress = 0 for p.progress < 100 {
time.Sleep(100 * time.Millisecond)
fmt.Print(".")
p.progress += 10
}
fmt.Println("\nFinished playing", source)
} func (p * WAVPlayer) Play (source string) {
fmt.Println("Playing WAV music", source) p.progress = 0 for p.progress < 100 {
time.Sleep(100 * time.Millisecond)
fmt.Print(".")
p.progress += 10
}
fmt.Println("\nFinished playing", source)
}
1.3.2)src/mp/play.go代码
package mp
import "fmt"
type Player interface {
Play(source string)
}
func Play(source, mtype string) {
var p Player
switch mtype {
case "MP3" :
p = &MP3Player{}
case "WAV" :
p = &WAVPlayer{}
default :
fmt.Println("Unsupported music type", mtype)
return
}
p.Play(source)
}
1.4)main package模块代码mplayer.go
package main import (
"bufio"
"fmt"
"os"
"strconv"
"strings" "mlib"
"mp"
) var lib * library.MusicManager
var id int = 1
var ctrl, signal chan int func handleLibCommands(tokens []string) {
switch tokens[1] {
case "list" :
for i := 0; i < lib.Len(); i++ {
e, _ := lib.Get(i)
fmt.Println(i + 1, ":", e.Name, e.Artist, e.Source, e.Type)
}
case "add" :
if len(tokens) == 7 {
id++
lib.Add(&library.MusicEntry { strconv.Itoa(id), tokens[2], tokens[3], tokens[4], tokens[5], tokens[6] })
} else {
fmt.Println("USAGE : lib add <name><artist><genre><source><type> (7 argv)")
}
case "remove" :
if len(tokens) == 3 {
lib.RemoveByName(tokens[2])
} else {
fmt.Println("USAGE: lib remove <name>")
}
default :
fmt.Println("Unrecogized lib command: ", tokens[1])
}
} func handlePlayCommands(tokens []string) {
if len(tokens) != 2 {
fmt.Println("USAGE : play <name>")
return
} e := lib.Find(tokens[1])
if e == nil {
fmt.Println("The music", tokens[1], "does not exist.")
return
} mp.Play(e.Source, e.Type)
} func main() {
fmt.Println(`
Enter following commands to control the player:
lib list --View the existing music lib
lib add <name><artist><genre><source><type> -- Add a music to the music lib
lib remove <name> --Remove the specified music from the lib
play <name> -- Play the specified music
`)
lib = library.NewMusicManager() r := bufio.NewReader(os.Stdin) for i := 0; i <= 100; i++ {
fmt.Print("Enter command-> ")
rawLine, _, _ := r.ReadLine() line := string(rawLine)
if line == "q" || line == "e" {
break
}
tokens := strings.Split(line, " ") if tokens[0] == "lib" {
handleLibCommands(tokens)
} else if tokens[0] == "play" {
handlePlayCommands(tokens)
} else {
fmt.Println("Unrecognized command :", tokens[0])
}
}
}
2)编译及运行
2.1)设置环境GOPATH
$ export GOPATH="/home/normal/musicplayer"
2.2)编译
$ go build
2.3)查看编译后的目录结构
.
├── mplayer.go
├── musicplayer
└── src
├── mlib
│ ├── manager.go
│ └── manager_test.go
└── mp
├── mp3.go
└── play.go
2.4)运行
$ ./musicplayer
Enter following commands to control the player:
lib list --View the existing music lib
lib add <name><artist><genre><source><type> -- Add a music to the music lib
lib remove <name> --Remove the specified music from the lib
play <name> -- Play the specified music
Enter command-> lib add a b c d e
Enter command-> lib list
: a b d e
Enter command-> play a
Unsupported music type e
Enter command-> lib remove a
Enter command-> lib add a b c d e MP3
USAGE : lib add <name><artist><genre><source><type> ( argv)
Enter command-> lib add a b c d MP3
Enter command-> lib list
: a b d MP3
Enter command-> play a
Playing MP3 music d
..........
Finished playing d
Enter command-> q
注:代码来源《Go语言编程》第三章,代码结构与原书有差别
GO语言练习:第二个工程--模拟音乐播放器的更多相关文章
- Java模拟音乐播放器 暂停与重新播放——线程如何控制另外一个线程的状态
package com.example.Thread; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEve ...
- [MFC] MFC音乐播放器 傻瓜级教程 网络 搜索歌曲 下载
>目录< >——————————————————————< 1.建立工程 1.建立一个MFC工程,命名为Tao_Music 2.选择为基本对话框 3.包含Windows So ...
- 仿酷狗音乐播放器开发日志二十四 选项设置窗体的实现(附328行xml布局源码)
转载请说明原出处,谢谢~~ 花了两天时间把仿酷狗的选项设置窗体做出来了,当然了只是做了外观.现在开学了,写代码的时间减少,所以整个仿酷狗的工程开发速度减慢了.今天把仿酷狗的选项设置窗体的布局代码分享出 ...
- 单片AT89C2051 + SD卡 + 3310LCD = 音乐播放器
http://www.amobbs.com/thread-4503884-1-1.html 这个小玩意,采用 ATMEL 的传统51MCU作主控制芯片,加上SD卡和显示屏,就可以作简单的音乐播放器了, ...
- STM32实现Airplay音乐播放器
AirPlay是苹果公司推出的一套无线音乐解决方案,我们手里的iPhone.iPad甚至是Apple Watch等设备还有电脑上的iTunes都支持AirPlay,但是支持AirPlay功能的音响设备 ...
- 基于Basys2开发板的简易电子琴和音乐播放器设计
背景:华中科技大学 电测综合实验 主要功能:Basys2开发板外接一个扬声器(或无源蜂鸣器也可)实现电子琴和音乐播放器的功能.其中由于开发板上只有4个按键,所以电子琴功能只做了4个音调,分别对应于4个 ...
- 【.NET 与树莓派】用 MPD 制作数字音乐播放器
树莓派的日常家居玩法多多,制作一台属于自己的数字音乐播放机是其中的一种.严格上说,树莓派是没有声卡的,其板载的 3.5 mm 音频孔实际是通过 PWM 来实现音频输出的(通过算法让PWM信号变成模拟信 ...
- 卡拉OK效果的实现-iOS音乐播放器
自己编写的音乐播放器偶然用到这个模块,发现没有思路,而且上网搜了搜,关于这方面的文章不是很多,没找到满意的结果,然后自己也是想了想,最终实现了这种效果,想通了发现其实很简单. 直接上原理: 第一种: ...
- Andriod小项目——在线音乐播放器
转载自: http://blog.csdn.net/sunkes/article/details/51189189 Andriod小项目——在线音乐播放器 Android在线音乐播放器 从大一开始就已 ...
随机推荐
- java Integer == 比较的小问题
示例代码: @Test public void testEquals() { Integer a = 127; Integer b = 127; if(a == b) { System.out.pri ...
- C#动态方法调用
此篇将介绍C#如何在运行时动态调用方法.当某些类型是运行时动态确定时,编译时的静态编码是无法解决这些动态对象或类的方法调用的.此篇则给你一把利剑,让动态对象的方法调用成为可能. 1.动态调用dll里的 ...
- php+jquery+ajax实现用户名验证
大多数情况下,jquery代码的编写,都要求我们将jquery的代码放在以下三种中任一个function里. 有三种写法,同样效果,有点像Window.onload,但也有不同,就是window.on ...
- apt-get常见错误——Unmet dependencies
转自:http://blog.sina.com.cn/s/blog_4980828b0100zicn.html 安装错误:“E: Unmet dependencies.”原因:非正常停止apt-get ...
- mysql 方法row_number()方法
1. SELECT t.*, @curRow := @curRow + 1 AS row_numberFROM structure tJOIN (SELECT @curR ...
- HDU 5791 Two DP
Two Problem Description Alice gets two sequences A and B. A easy problem comes. How many pair of ...
- 简单解释Windows如何使用FS段寄存器
详见附件 jpg改rar
- Linux学习笔记(12)用户和用户组管理
越是对服务器安全性要求高的服务器,越需要建立合理的用户权限等级制度和服务器操作规范.在Linux中主要是通过用户配置文件来查看和修改用户信息. 1 用户信息文件 (1)用户信息文件/etc/passw ...
- 关于如何在MFC工程中输入不同的数据进行调试
我们可以采用c++的文件输入输出来进行调试 这样就绕过了不能使用黑窗口输入数据就不能调试的思维定式 不是黑窗口的我们都可以考虑用文件流输入输出 或者用控件来输入? http://blog.csdn.n ...
- JavaScript模拟函数重载
JavaScript是没有函数重载的,但是我们可以通过其他方法来模拟函数重载,如下所示: <!DOCTYPE html> <html> <head> <met ...