这里的技巧在于学习如何定义数据结构,更新数据结构,在哪里用指针或是地址来更新。

manger.go

package library

import "errors"

type MusicEntry struct {
	Id     string
	Name   string
	Artist 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 {
	if len(m.musics) == 0 {
		return nil
	}

	for _, m := range m.musics {
		if m.Name == name {
			return &m
		}
	}
	return nil
}

  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)
}

  mp3.go

package mp

import (
	"fmt"
	"time"
)

type MP3Player 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)
}

  mplayer.go

// SMP project main.go
package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"

	"SMP/mlib"
	"SMP/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) == 6 {
				id++
				lib.Add(&library.MusicEntry{strconv.Itoa(id),
					tokens[2], tokens[3], tokens[4], tokens[5]})
			} else {
				fmt.Println("USAGE: lib add <name><artist><source><type>")
			}
		}
	case "remove":
		if len(tokens) == 3 {
			lib.RemoveByName(tokens[2])
		} else {
			fmt.Println("USAGE: lib remove <name>")
		}
	default:
		fmt.Println("Unrecognized lib command: ", tokens[1])
	}
}

func handlePlayCommand(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><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 {
		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" {
			handlePlayCommand(tokens)
		} else {
			fmt.Println("Unrecognized command: ", tokens[0])
		}
	}
}

  

一个用go写的模拟mp3文字界面播放程序的更多相关文章

  1. WPF模拟探照灯文字

    原文:WPF模拟探照灯文字 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/yangyisen0713/article/details/1835936 ...

  2. php调用一个c语言写的接口问题

    用php调用一个c语言写的soap接口时,遇到一个问题:不管提交的数据正确与否,都无法请求到接口 1.用php标准的soap接口去请求 2.拼接xml数据去请求 以上两种方式都不正确 解决办法:php ...

  3. 只是一个用EF写的一个简单的分页方法而已

    只是一个用EF写的一个简单的分页方法而已 慢慢的写吧.比如,第一步,先把所有数据查询出来吧. //第一步. public IQueryable<UserInfo> LoadPagesFor ...

  4. 一个用C++写的Json解析与处理库

    什么是Json?这个库能做什么? JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is e ...

  5. 干净win7要做几步才能运行第一个Spring MVC 写的动态web程序

    干净win7要做几步才能运行第一个Spring MVC 写的动态web程序: 1. 下载安装jdk 2. 配置Java环境变量 3. 测试一下第1,2两步是否完全成功:http://jingyan.b ...

  6. 用MXnet实战深度学习之一:安装GPU版mxnet并跑一个MNIST手写数字识别

    用MXnet实战深度学习之一:安装GPU版mxnet并跑一个MNIST手写数字识别 http://phunter.farbox.com/post/mxnet-tutorial1 用MXnet实战深度学 ...

  7. 一个用beego写的API项目

    beego-api 一个使用beego写的API 支持Api日志 支持Swagger注解文档 项目地址: https://github.com/eternity-wdd/beego-api 使用说明 ...

  8. 一个用python写的比特币均线指标

    https://blog.csdn.net/gsl222/article/details/104554397 https://github.com/yyy999/auto_ma912 一个用pytho ...

  9. Java获取音频文件(MP3)的播放时长

    最近的一个项目需要按照时间播放mp3文件,例如,播放10分钟的不同音乐. 这就意味着我得事先知道mp3文件的播放时长,以决定播放几遍这个文件. 方案一:Java的方式 找第三方的库,真的感谢这些提供j ...

随机推荐

  1. Codeforces Round #311 (Div. 2)B. Pasha and Tea二分

    B. Pasha and Tea time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  2. D-query SPOJ - DQUERY(莫队)统计不同数的数量

    Given a sequence of n numbers a1, a2, ..., an and a number of d-queries. A d-query is a pair (i, j) ...

  3. DOM学习控件定位和案例

    Dom中有多种定位属性,下面是一个简单案例 <html><!--制作一个会跟着鼠标走的图像,还有控件定位的案例--> <head> <title>doc ...

  4. ZooKeeper管理员指南——部署与管理ZooKeeper

    1.部署 本章节主要讲述如何部署ZooKeeper,包括以下三部分的内容: 系统环境 集群模式的配置 单机模式的配置 系统环境和集群模式配置这两节内容大体讲述了如何部署一个能够用于生产环境的ZK集群. ...

  5. Mybatis(4) 映射文件-参数处理

    参数处理: 单参数处理: mybatis 不会做任何特殊处理. #{key} : key 可以写任何字段取出参数值. 测试方法: mapper接口: mapper.xml: 控制台: 多参数处理: m ...

  6. [LeetCode] 17. Letter Combinations of a Phone Number ☆☆

    Given a digit string, return all possible letter combinations that the number could represent. A map ...

  7. 可能是国内最火的开源项目 —— C/C++ 篇

    程序员们,在北上广你还能买房吗? >>>   推荐阅读: 可能是最火的开源项目 -- Java 篇 可能是国内最火的开源项目 -- PHP 篇 可能是国内最火的开源项目 -- Pyt ...

  8. RDLC - 后台代码直接导出Excel/PDF/Word格式

    最近做报表功能,用到了.net的报表组件rdlc. 其中有个功能就是后台代码直接输出Excel/PDF/Word格式的文件,网上看了些资源,做个总结: 参考地址 我直接贴出代码: //自动导出exce ...

  9. 【BZOJ3191】【JLOI2013】卡牌游戏 [DP]

    卡牌游戏 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description   N个人坐成一圈玩游戏.一开始我 ...

  10. JS之document对象(找元素、操作内容、操作属性、操作样式及4道例题)

    document对象 一.找元素 1.根据id找 示例: <input id = "a" type="button" value="找元素&qu ...