forked from albertz/music-player
-
Notifications
You must be signed in to change notification settings - Fork 0
/
test_ffmpeg.py
143 lines (122 loc) · 3.65 KB
/
test_ffmpeg.py
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
# MusicPlayer, https://github.com/albertz/music-player
# Copyright (c) 2012, Albert Zeyer, www.az2000.de
# All rights reserved.
# This code is under the 2-clause BSD license, see License.txt in the root directory of this project.
import better_exchook
better_exchook.install()
import ffmpeg
# ffmpeg log levels: {0:panic, 8:fatal, 16:error, 24:warning, 32:info, 40:verbose}
ffmpeg.setFfmpegLogLevel(20)
try:
import faulthandler
faulthandler.enable(all_threads=True)
except ImportError:
print "note: module faulthandler not available"
class Song:
def __init__(self, fn):
self.url = fn
self.f = open(fn)
def __eq__(self, other):
return self.url == other.url
def readPacket(self, bufSize):
s = self.f.read(bufSize)
#print "readPacket", self, bufSize, len(s)
return s
def seekRaw(self, offset, whence):
r = self.f.seek(offset, whence)
#print "seekRaw", self, offset, whence, r, self.f.tell()
return self.f.tell()
files = [
"~/Music/Classic/Glenn Gould Plays Bach/Two- & Three-Part Inventions - Gould/19 Bach - Invention 13 in a (BWV 784).mp3",
"~/Music/Rock/Tool/Lateralus/09 Lateralus.flac",
"~/Music/Cults - Cults 7/Cults - Cults 7- - 03 The Curse.flac",
"~/Music/Special/zorba/(01) - Theme From Zorba The Greek.ogg",
"~/Music/Classic/Glenn Gould Plays Bach/French Suites, BWV812-7 - Gould/Bach, French Suite 5 in G, BWV816 - 5 Bourree.mp3",
"~/Music/Electronic/Von Paul Kalkbrenner - Aaron.mp3",
"~/Music/Electronic/One Day_Reckoning Song (Wankelmut Remix) - Asaf Avidan & the Mojos.mp3",
]
import sys
files = sys.argv[1:] + files
import os
files = map(os.path.expanduser, files)
i = 0
def songs():
global i, files
while True:
yield Song(files[i])
i += 1
if i >= len(files): i = 0
def peekSongs(n):
nexti = i + 1
if nexti >= len(files): nexti = 0
return map(Song, files[nexti:] + files[:nexti])
player = ffmpeg.createPlayer()
player.outSamplerate = 48000
player.queue = songs()
player.peekQueue = peekSongs
player.playing = True
def formatTime(t):
if t is None: return "?"
mins = long(t // 60)
t -= mins * 60
hours = mins // 60
mins -= hours * 60
if hours: return "%02i:%02i:%02.0f" % (hours,mins,t)
return "%02i:%02.0f" % (mins,t)
import termios
def prepareStdin():
fd = sys.stdin.fileno()
if os.isatty(fd):
old = termios.tcgetattr(fd)
new = termios.tcgetattr(fd)
new[3] = new[3] & ~termios.ICANON & ~termios.ECHO
# http://www.unixguide.net/unix/programming/3.6.2.shtml
#new[6] [termios.VMIN] = 1
#new[6] [termios.VTIME] = 0
new[6] [termios.VMIN] = 0
#timeout *= 10 # 10ths of second
#if timeout > 0 and timeout < 1: timeout = 1
timeout = 1
new[6] [termios.VTIME] = timeout
termios.tcsetattr(fd, termios.TCSANOW, new)
termios.tcsendbreak(fd,0)
import atexit
atexit.register(lambda: termios.tcsetattr(fd, termios.TCSANOW, old))
def getchar(timeout = 0):
fd = sys.stdin.fileno()
ch = os.read(fd,7)
return(ch)
prepareStdin()
import time
#sys.stdout.write("\n")
while True:
sys.stdout.write("\r\033[K") # clear line
if player.playing: sys.stdout.write("playing, ")
else: sys.stdout.write("paused, ")
curSong = player.curSong
if curSong:
sys.stdout.write(
os.path.basename(curSong.url) + " : " +
formatTime(player.curSongPos) + " / " +
formatTime(player.curSongLen))
else:
sys.stdout.write("no song")
# time.sleep(0.05)
ch = getchar(0.1)
#sys.stdout.write(" " + repr(ch))
if ch == "\x1b[D": # left
player.seekRel(-10)
elif ch == "\x1b[C": #right
player.seekRel(10)
elif ch == "\x1b[A": #up
pass
elif ch == "\x1b[B": #down
pass
elif ch == "\n": # return
player.nextSong()
elif ch == " ":
player.playing = not player.playing
elif ch == "q":
print
sys.exit(0)
sys.stdout.flush()