forked from pkulchenko/wxlua
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmedia.wx.lua
More file actions
319 lines (265 loc) · 12.1 KB
/
media.wx.lua
File metadata and controls
319 lines (265 loc) · 12.1 KB
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
-----------------------------------------------------------------------------
-- Name: media.wx.lua
-- Purpose: wxMediaCtrl wxLua sample
-- Author: John Labenski
-- Modified by:
-- Created: 07/01/2007
-- RCS-ID:
-- Copyright: (c) 2007 John Labenski. All rights reserved.
-- Licence: wxWidgets licence
-----------------------------------------------------------------------------
-- Load the wxLua module, does nothing if running from wxLua, wxLuaFreeze, or wxLuaEdit
package.cpath = package.cpath..";./?.dll;./?.so;../lib/?.so;../lib/vc_dll/?.dll;../lib/bcc_dll/?.dll;../lib/mingw_dll/?.dll;"
require("wx")
frame = nil -- main wxFrame
mediaCtrl = nil -- wxMediaCtrl player
playButton = nil -- wxButton to "play"
pauseButton = nil -- wxButton to "pause"
stopButton = nil -- wxButton to "stop"
timer = nil -- wxTimer to update position in media
loadedMedia = false -- set to true if media is ok
fileName = "" -- Name of the loaded file
settingPos = false -- true when pos slider is being changed by user
slider_range = 10000 -- all sliders have this range
ID_LOADFILE = 1000
ID_PLAY = 1001
ID_PAUSE = 1002
ID_STOP = 1003
ID_VOLUME = 1004
ID_POSITON = 1005
ID_POSTEXT = 1006
-- ---------------------------------------------------------------------------
-- Convert milliseconds to MM:SS
-- ---------------------------------------------------------------------------
function msToMMSS(ms)
local m = math.floor(ms/(60*1000))
local s = math.floor((ms - m*60*1000)/1000)
return string.format("%02d:%02d", m, s)
end
-- ---------------------------------------------------------------------------
-- Update the GUI controls based on the mediaCtrl
-- ---------------------------------------------------------------------------
function UpdateButtons()
local play_ok = false
local pause_ok = false
local stop_ok = false
if loadedMedia then
-- Note: state may be -1 after first loading a file
local state = mediaCtrl:GetState()
if state == wx.wxMEDIASTATE_PLAYING then
play_ok = false
pause_ok = true
stop_ok = true
elseif state == wx.wxMEDIASTATE_PAUSED then
play_ok = true
pause_ok = false
stop_ok = true
else -- if state == wx.wxMEDIASTATE_STOPPED then
play_ok = true
pause_ok = false
stop_ok = false
end
end
playButton:Enable(play_ok)
pauseButton:Enable(pause_ok)
stopButton:Enable(stop_ok)
volumeSlider:SetValue(mediaCtrl:GetVolume()*slider_range)
end
-- ---------------------------------------------------------------------------
-- Entry point into the program
-- ---------------------------------------------------------------------------
function main()
-- create the wxFrame window
frame = wx.wxFrame( wx.NULL, -- no parent for toplevel windows
wx.wxID_ANY, -- don't need a wxWindow ID
"wxLua Media Demo", -- caption on the frame
wx.wxDefaultPosition, -- let system place the frame
wx.wxSize(450, 450), -- set the size of the frame
wx.wxDEFAULT_FRAME_STYLE ) -- use default frame styles
frame:Connect(wx.wxEVT_CLOSE_WINDOW,
function (event)
event:Skip()
if timer then
timer:Stop() -- always stop before exiting or deleting it
timer:delete()
timer = nil
end
end)
-- -----------------------------------------------------------------------
-- create a simple file menu
local fileMenu = wx.wxMenu()
fileMenu:Append(ID_LOADFILE, "Load media...\tCtrl+O", "Load a file to play...")
fileMenu:AppendSeparator()
fileMenu:Append(wx.wxID_EXIT, "E&xit\tCtrl+Q", "Quit the program")
-- create a simple help menu
local helpMenu = wx.wxMenu()
helpMenu:Append(wx.wxID_ABOUT, "&About", "About the wxLua Media Application")
-- create a menu bar and append the file and help menus
local menuBar = wx.wxMenuBar()
menuBar:Append(fileMenu, "&File")
menuBar:Append(helpMenu, "&Help")
-- attach the menu bar into the frame
frame:SetMenuBar(menuBar)
-- create a simple status bar
frame:CreateStatusBar(1)
frame:SetStatusText("Welcome to wxLua.")
-- -----------------------------------------------------------------------
panel = wx.wxPanel(frame, wx.wxID_ANY)
mediaCtrl = wx.wxMediaCtrl(panel, wx.wxID_ANY, "",
wx.wxDefaultPosition, wx.wxSize(200, 200))
playButton = wx.wxButton(panel, ID_PLAY, "Play")
pauseButton = wx.wxButton(panel, ID_PAUSE, "Pause")
stopButton = wx.wxButton(panel, ID_STOP, "Stop")
volumeSlider = wx.wxSlider(panel, ID_VOLUME, slider_range, 0, slider_range)
buttonSizer = wx.wxFlexGridSizer(1, 0, 5, 5)
buttonSizer:AddGrowableCol(4)
buttonSizer:Add(playButton, 0, 0)
buttonSizer:Add(pauseButton, 0, 0)
buttonSizer:Add(stopButton, 0, 0)
buttonSizer:Add(wx.wxStaticText(panel, wx.wxID_ANY, "Volume : "), 0, wx.wxALIGN_CENTER_VERTICAL)
buttonSizer:Add(volumeSlider, 1, wx.wxEXPAND)
posSlider = wx.wxSlider(panel, ID_POSITON, 0, 0, slider_range)
posText = wx.wxStaticText(panel, ID_POSTEXT, "Position 00:00/00:00 ")
posSizer = wx.wxFlexGridSizer(1, 0, 5, 5)
posSizer:AddGrowableCol(1)
posSizer:Add(posText, 0, wx.wxALIGN_CENTER_VERTICAL)
posSizer:Add(posSlider, 1, wx.wxEXPAND)
mainSizer = wx.wxFlexGridSizer(0, 1, 5, 5)
mainSizer:AddGrowableRow(0)
mainSizer:AddGrowableCol(0)
mainSizer:Add(mediaCtrl, 1, wx.wxEXPAND, 0)
mainSizer:Add(buttonSizer, 0, wx.wxEXPAND, 0)
mainSizer:Add(posSizer, 0, wx.wxEXPAND, 0)
panel:SetSizer(mainSizer)
mainSizer:SetSizeHints(frame)
UpdateButtons()
-- -----------------------------------------------------------------------
panel:Connect(ID_PLAY, wx.wxEVT_COMMAND_BUTTON_CLICKED,
function (event)
local ok = mediaCtrl:Play()
if not ok then
wx.wxMessageBox(string.format("Unable to play %s: Unsupported format?", fileName),
"wxLua Media Demo",
wx.wxICON_ERROR + wx.wxOK)
end
end )
panel:Connect(ID_PAUSE, wx.wxEVT_COMMAND_BUTTON_CLICKED,
function (event)
local ok = mediaCtrl:Pause()
if not ok then
wx.wxMessageBox(string.format("Unable to pause %s: Unsupported format?", fileName),
"wxLua Media Demo",
wx.wxICON_ERROR + wx.wxOK)
end
end )
panel:Connect(ID_STOP, wx.wxEVT_COMMAND_BUTTON_CLICKED,
function (event)
local ok = mediaCtrl:Stop()
if not ok then
wx.wxMessageBox(string.format("Unable to stop %s: Unsupported format?", fileName),
"wxLua Media Demo",
wx.wxICON_ERROR + wx.wxOK)
end
end )
panel:Connect(ID_VOLUME, wx.wxEVT_SCROLL_THUMBRELEASE,
function (event)
local pos = event:GetPosition()
mediaCtrl:SetVolume(pos/slider_range)
end )
panel:Connect(ID_POSITON, wx.wxEVT_SCROLL_THUMBTRACK,
function (event) settingPos = true end)
local function scroll_position(event)
if loadedMedia then
local pos = event:GetPosition()
local len = mediaCtrl:Length()
print(pos, len)
local ok = mediaCtrl:Seek(math.floor(len*pos/slider_range))
if ok == wx.wxInvalidOffset then
wx.wxMessageBox(string.format("Unable to seek in %s: Unsupported format?", fileName),
"wxLua Media Demo",
wx.wxICON_ERROR + wx.wxOK)
end
end
settingPos = false
end
panel:Connect(ID_POSITON, wx.wxEVT_SCROLL_THUMBRELEASE, scroll_position)
panel:Connect(ID_POSITON, wx.wxEVT_SCROLL_TOP, scroll_position)
panel:Connect(ID_POSITON, wx.wxEVT_SCROLL_BOTTOM, scroll_position)
panel:Connect(ID_POSITON, wx.wxEVT_SCROLL_LINEUP, scroll_position)
panel:Connect(ID_POSITON, wx.wxEVT_SCROLL_LINEDOWN, scroll_position)
panel:Connect(ID_POSITON, wx.wxEVT_SCROLL_PAGEUP, scroll_position)
panel:Connect(ID_POSITON, wx.wxEVT_SCROLL_PAGEDOWN, scroll_position)
mediaCtrl:Connect(wx.wxEVT_MEDIA_STATECHANGED,
function (event)
UpdateButtons()
end)
-- -----------------------------------------------------------------------
timer = wx.wxTimer(panel)
panel:Connect(wx.wxEVT_TIMER,
function (event)
local len = 1 -- avoid /0
local pos = 0
local str = "Position 00:00/00:00"
if loadedMedia then
len = mediaCtrl:Length()
pos = mediaCtrl:Tell()
str = string.format("Position %s/%s", msToMMSS(pos), msToMMSS(len))
end
if not settingPos then
posSlider:SetValue(slider_range*pos/len)
end
if posText:GetLabel() ~= str then
posText:SetLabel(str)
end
end)
timer:Start(300)
-- -----------------------------------------------------------------------
frame:Connect(ID_LOADFILE, wx.wxEVT_COMMAND_MENU_SELECTED,
function (event)
local dlg = wx.wxFileDialog(frame, "Choose a media file",
wx.wxGetCwd(), "", "All Files (*)|*|MP3 Music Files (*.mp3)|*.mp3|MPG Video Files (*.mpg)|*.mpg|AVI Movie Files (*.avi)|*.avi",
wx.wxFD_OPEN + wx.wxFD_FILE_MUST_EXIST + wx.wxFD_CHANGE_DIR )
if dlg:ShowModal() == wx.wxID_OK then
local filepath = dlg:GetPath()
loadedMedia = false
fileName = ""
if not mediaCtrl:Load(filepath) then
wx.wxMessageBox(string.format("Unable to load %s: Unsupported format?", filepath),
"wxLua Media Demo",
wx.wxICON_ERROR + wx.wxOK)
else
posSlider:SetValue(0)
loadedMedia = true
fileName = dlg:GetFilename()
local ms = mediaCtrl:Length()
local s = mediaCtrl:GetBestSize()
frame:SetStatusText(string.format("Loaded: '%s' Length %s Size %dx%d", fileName, msToMMSS(ms), s:GetWidth(), s:GetHeight()))
mediaCtrl:SetInitialSize()
panel:GetSizer():Layout()
end
end
dlg:Destroy()
UpdateButtons()
end )
-- connect the selection event of the exit menu item to an
-- event handler that closes the window
frame:Connect(wx.wxID_EXIT, wx.wxEVT_COMMAND_MENU_SELECTED,
function (event) frame:Close(true) end )
-- connect the selection event of the about menu item
frame:Connect(wx.wxID_ABOUT, wx.wxEVT_COMMAND_MENU_SELECTED,
function (event)
wx.wxMessageBox('This is the "About" dialog of the Media wxLua sample.\n'..
wxlua.wxLUA_VERSION_STRING.." built with "..wx.wxVERSION_STRING,
"About wxLua Media",
wx.wxOK + wx.wxICON_INFORMATION,
frame)
end )
-- show the frame window
frame:Show(true)
end
main()
-- Call wx.wxGetApp():MainLoop() last to start the wxWidgets event loop,
-- otherwise the wxLua program will exit immediately.
-- Does nothing if running from wxLua, wxLuaFreeze, or wxLuaEdit since the
-- MainLoop is already running or will be started by the C++ program.
wx.wxGetApp():MainLoop()