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在线音乐播放器 从大一开始就已 ...
随机推荐
- T-SQL 常用语句
1. 查看 Table 或者 Column 被那些object(存储过程.函数或View)调用. select a.* from sysobjects a, syscomments b where a ...
- phpcms v9 常用调用标签(全)
本文介绍phpcms v9中模板标签使用说明. {template ) {==} {/,,)} loop是data的时候用{thumb($v[thumb],,)} 分页标签------{$ ...
- C语言中的static 详细分析
转自:http://blog.csdn.net/keyeagle/article/details/6708077/ google了近三页的关于C语言中static的内容,发现可用的信息很少,要么长篇大 ...
- 基于能量收集的智能家居-2013国家级大学生创业实践项目申报_商业计划书_V0.2
SmartHome项目商业计划 基于能量收集的 免电池无线智能家居系统 IA-SmartHome团队 2012.12 l 基于无线的智能家居解决方案,节省施工成本: l 基于能 ...
- LayoutInflater(四)
如果说要按类型来划分的话,自定义View的实现方式大概可以分为三种,自绘控件.组合控件.以及继承控件.那么下面我们就来依次学习一下,每种方式分别是如何自定义View的. 一.自绘控件 自绘控件的意思就 ...
- 及其简短的Splay代码
#include <stdio.h> #include <queue> #include <algorithm> #include <stdlib.h> ...
- AES128和AES256主要区别和安全程度是多少?他们对于机器的消耗是怎样的?两者性能如何?实际开发如何选择?
高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准.这个标准用来替代原先的DES, ...
- 深入理解KMP算法
前言:本人最近在看<大话数据结构>字符串模式匹配算法的内容,但是看得很迷糊,这本书中这块的内容感觉基本是严蔚敏<数据结构>的一个翻版,此书中给出的代码实现确实非常精炼,但是个人 ...
- 从零开始---控制台用c写俄罗斯方块游戏(1)
从零开始---控制台用c写俄罗斯方块游戏(1) 很少写博文,一来自身知识有限,二来自己知道,已经有很多这样的博文了,三就是因为懒,文笔也一般,四来刚出来工作,时间也不多 之所以写这篇博文,是因为应群里 ...
- 廖雪峰js教程笔记3
JavaScript的函数在查找变量时从自身函数定义开始,从"内"向"外"查找.如果内部函数定义了与外部函数重名的变量,则内部函数的变量将"屏蔽&qu ...