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语言练习:第二个工程--模拟音乐播放器的更多相关文章

  1. Java模拟音乐播放器 暂停与重新播放——线程如何控制另外一个线程的状态

    package com.example.Thread; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEve ...

  2. [MFC] MFC音乐播放器 傻瓜级教程 网络 搜索歌曲 下载

    >目录< >——————————————————————< 1.建立工程  1.建立一个MFC工程,命名为Tao_Music 2.选择为基本对话框 3.包含Windows So ...

  3. 仿酷狗音乐播放器开发日志二十四 选项设置窗体的实现(附328行xml布局源码)

    转载请说明原出处,谢谢~~ 花了两天时间把仿酷狗的选项设置窗体做出来了,当然了只是做了外观.现在开学了,写代码的时间减少,所以整个仿酷狗的工程开发速度减慢了.今天把仿酷狗的选项设置窗体的布局代码分享出 ...

  4. 单片AT89C2051 + SD卡 + 3310LCD = 音乐播放器

    http://www.amobbs.com/thread-4503884-1-1.html 这个小玩意,采用 ATMEL 的传统51MCU作主控制芯片,加上SD卡和显示屏,就可以作简单的音乐播放器了, ...

  5. STM32实现Airplay音乐播放器

    AirPlay是苹果公司推出的一套无线音乐解决方案,我们手里的iPhone.iPad甚至是Apple Watch等设备还有电脑上的iTunes都支持AirPlay,但是支持AirPlay功能的音响设备 ...

  6. 基于Basys2开发板的简易电子琴和音乐播放器设计

    背景:华中科技大学 电测综合实验 主要功能:Basys2开发板外接一个扬声器(或无源蜂鸣器也可)实现电子琴和音乐播放器的功能.其中由于开发板上只有4个按键,所以电子琴功能只做了4个音调,分别对应于4个 ...

  7. 【.NET 与树莓派】用 MPD 制作数字音乐播放器

    树莓派的日常家居玩法多多,制作一台属于自己的数字音乐播放机是其中的一种.严格上说,树莓派是没有声卡的,其板载的 3.5 mm 音频孔实际是通过 PWM 来实现音频输出的(通过算法让PWM信号变成模拟信 ...

  8. 卡拉OK效果的实现-iOS音乐播放器

    自己编写的音乐播放器偶然用到这个模块,发现没有思路,而且上网搜了搜,关于这方面的文章不是很多,没找到满意的结果,然后自己也是想了想,最终实现了这种效果,想通了发现其实很简单. 直接上原理: 第一种: ...

  9. Andriod小项目——在线音乐播放器

    转载自: http://blog.csdn.net/sunkes/article/details/51189189 Andriod小项目——在线音乐播放器 Android在线音乐播放器 从大一开始就已 ...

随机推荐

  1. WPF 创建自定义窗体

    在前面的一篇博客"WPF 自定义Metro Style窗体",展示了如何创建一个类似于Metro Style的Window,并在程序中使用.但是这个窗体不能够自由的改变大小.今天的 ...

  2. hdu 1404 找sg ***

    HDU 1404  Digital Deletions 一串由0~9组成的数字,可以进行两个操作:1.把其中一个数变为比它小的数:2.把其中一个数字0及其右边的所以数字删除. 两人轮流进行操作,最后把 ...

  3. linux使用读写锁pthread_rwlock_t

    转自:http://blog.csdn.net/onlyou930/article/details/6755593 使用读写锁 配置读写锁的属性之后,即可初始化读写锁.以下函数用于初始化或销毁读写锁. ...

  4. C#中var和dynamic

    var与dynamic这两个关键字,只是看起来很相似,仅此而已!var表示“变量的类型是在编译时决定的”,但是dynamic表 示“变量的类型是在运行时决定的”.因此,dynamic与var具有截然不 ...

  5. C和C++的头文件总结

    stdafx.h 的英文全称为:Standard Application Framework Extensions(标准应用程序框架的扩展) iostream.h 是input output stre ...

  6. jfreeChart柱状图各属性详细设置

    一. 下载与环境配置 此最新版本为 1.0.13 解压jfreechart-1.0.13.zip 将lib目录下的jfreechart-1.0.13.jar .jcommon-1.0.16.jar 复 ...

  7. Linux C编程(2) dgb调试

    1. 首先编写一个用于调试的测试程序test.c #include <stdio.h> int get_sum(int n) { ,i; ; i <=n ; i++) { sum+= ...

  8. JMeter常用字符串相关函数

    JMeter的惯用函数使用-字符串相关 主要的函数如下:1.将字符串转为大写或小写: ${__lowercase(Hello,)}  ${__uppercase(Hello,)}2.生成字符串:  _ ...

  9. zjoi2016 day1【bzoj4455】【bzoj4456】

    首先做了T2的旅行者,看到bz上面过的人数比较多.. 考试的时候完全没有想太多.一闪而过了分块思想,然后就没有然后了.. 大视野上面有题解,竟然是一个初中生写的..? 正解其实是“分治”,每次选择中轴 ...

  10. mybatis做like模糊查询

    http://www.cnblogs.com/cyttina/p/3894428.html