-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
149 lines (126 loc) · 3.34 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package main
import (
"fmt"
"io"
"io/ioutil"
"log"
"os"
"time"
pb "gopkg.in/cheggaaa/pb.v1"
mp3 "github.com/hajimehoshi/go-mp3"
"github.com/hajimehoshi/oto"
flags "github.com/jessevdk/go-flags"
)
const defaultMP3Dir = "data"
const defaultMP3File = "knocking_a_wooden_door2.mp3"
func run(mp3FilePath string) error {
f, err := os.Open(mp3FilePath)
if err != nil {
return err
}
defer f.Close()
d, err := mp3.NewDecoder(f)
if err != nil {
return err
}
defer d.Close()
p, err := oto.NewPlayer(d.SampleRate(), 2, 2, 8192)
if err != nil {
return err
}
defer p.Close()
if _, err := io.Copy(p, d); err != nil {
return err
}
return nil
}
var opts struct {
Minute float32 `short:"m" long:"minute" default:"30" description:"init limit time(minute)"`
MP3File string `short:"f" long:"file" description:"sound file for notice"`
}
func existsFile(path string) bool {
_, err := os.Stat(path)
return err == nil
}
// data/knocking_a_wooden_door2.mp3 がないならば作成する。
// MP3ファイルは http://taira-komori.jpn.org/index.html から拝借したものを埋め込んでいる。
func setupDefaultMP3(temporaryDir string) {
if !existsFile(getDefaultMP3Path(temporaryDir)) {
data, err := Asset(getDefaultMP3AssetPath())
if err != nil {
panic(err)
}
ioutil.WriteFile(getDefaultMP3Path(temporaryDir), data, os.ModePerm)
}
}
func getDefaultMP3AssetPath() string {
return defaultMP3Dir + "/" + defaultMP3File
}
func getDefaultMP3Path(temporaryDir string) string {
return temporaryDir + "/" + defaultMP3File
}
func getTemporaryDir() (string, error) {
dir := os.TempDir() + "/time_to_sound_temporary"
if existsFile(dir) {
return dir, nil
}
err := os.Mkdir(dir, 0700)
if err != nil {
return "", err
}
return dir, nil
}
func main() {
// temporaryDir, _ := ioutil.TempDir("", "time_to_sound")
temporaryDir, _ := getTemporaryDir()
defer os.RemoveAll(temporaryDir)
_, err := flags.ParseArgs(&opts, os.Args)
if err != nil {
panic(err)
}
showMP3FilePath := opts.MP3File
if len(opts.MP3File) == 0 {
opts.MP3File = getDefaultMP3Path(temporaryDir)
showMP3FilePath = getDefaultMP3AssetPath()
}
fmt.Printf("Minute: %v\n", opts.Minute)
fmt.Printf("MP3File: %v\n", showMP3FilePath)
if opts.Minute < 0 {
panic("invalid initial time")
}
setupDefaultMP3(temporaryDir)
// MP3ファイルの存在チェック
if !existsFile(opts.MP3File) {
panic("MP3file was not found")
}
const timeLayout = "2006-01-02 15:04:05"
fmt.Printf("START: %v\n", time.Now().Format(timeLayout))
// 1秒ごとに進捗バーを伸ばす。
secondCount := int(opts.Minute * 60)
bar := pb.StartNew(secondCount)
// 1秒ごとに反応するティッカー。
ticker := time.NewTicker(time.Second)
stop := make(chan bool)
go func() {
loop:
for {
select {
case _ = <-ticker.C:
bar.Increment()
case <-stop:
break loop
}
}
}()
// 指定された時間だけスリープする。
time.Sleep(time.Duration(secondCount*1000) * time.Millisecond)
ticker.Stop()
close(stop)
// 残りのバーをすべて埋める。
bar.Add(secondCount - int(bar.Get()))
bar.FinishPrint("END: " + time.Now().Format(timeLayout))
err = run(opts.MP3File)
if err != nil {
log.Fatal(err)
}
}