OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <deque> | 5 #include <deque> |
6 #include <iomanip> | 6 #include <iomanip> |
7 #include <iostream> | 7 #include <iostream> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "examples/media_test/keystroke.h" | 10 #include "examples/media_test/keystroke.h" |
(...skipping 16 matching lines...) Loading... |
27 | 27 |
28 // ApplicationDelegate implementation. | 28 // ApplicationDelegate implementation. |
29 void Initialize(mojo::ApplicationImpl* app) override { | 29 void Initialize(mojo::ApplicationImpl* app) override { |
30 app_ = app; | 30 app_ = app; |
31 ProcessArgs(app->args()); | 31 ProcessArgs(app->args()); |
32 | 32 |
33 std::cout << std::endl << "MEDIA TEST" << std::endl << std::endl; | 33 std::cout << std::endl << "MEDIA TEST" << std::endl << std::endl; |
34 | 34 |
35 if (input_file_names_.empty()) { | 35 if (input_file_names_.empty()) { |
36 std::cout << "Please provide the names of the files you want to play;" | 36 std::cout << "Please provide the names of the files you want to play;" |
37 << " for example:" << std::endl; | 37 << " for example:" << std::endl; |
38 std::cout << "mojo/devtools/common/mojo_run \\" << std::endl; | 38 std::cout << "mojo/devtools/common/mojo_run \\" << std::endl; |
39 std::cout << " \"https://core.mojoapps.io/media_test.mojo \\" | 39 std::cout << " \"https://core.mojoapps.io/media_test.mojo \\" |
40 << std::endl; | 40 << std::endl; |
41 std::cout << " file:///usr/local/google/home/you/superstition.ogg \\" | 41 std::cout << " file:///usr/local/google/home/you/superstition.ogg \\" |
42 << std::endl; | 42 << std::endl; |
43 std::cout << " file:///usr/local/google/home/you/higherground.ogg\"" | 43 std::cout << " file:///usr/local/google/home/you/higherground.ogg\"" |
44 << std::endl << std::endl; | 44 << std::endl |
| 45 << std::endl; |
45 base::MessageLoop::current()->Quit(); | 46 base::MessageLoop::current()->Quit(); |
46 return; | 47 return; |
47 } | 48 } |
48 | 49 |
49 std::cout << " <enter> play/pause" << std::endl; | 50 std::cout << " <enter> play/pause" << std::endl; |
50 std::cout << " n<enter> next file" << std::endl; | 51 std::cout << " n<enter> next file" << std::endl; |
51 std::cout << " p<enter> previous file" << std::endl; | 52 std::cout << " p<enter> previous file" << std::endl; |
52 std::cout << " <digit><enter> seek (0% - 90%)" << std::endl; | 53 std::cout << " <digit><enter> seek (0% - 90%)" << std::endl; |
53 std::cout << " q<enter> quit" << std::endl << std::endl; | 54 std::cout << " q<enter> quit" << std::endl << std::endl; |
54 | 55 |
(...skipping 13 matching lines...) Loading... |
68 CreateNewMediaTest(); | 69 CreateNewMediaTest(); |
69 Poll(); | 70 Poll(); |
70 } | 71 } |
71 | 72 |
72 bool ConfigureIncomingConnection( | 73 bool ConfigureIncomingConnection( |
73 mojo::ApplicationConnection* connection) override { | 74 mojo::ApplicationConnection* connection) override { |
74 return true; | 75 return true; |
75 } | 76 } |
76 | 77 |
77 private: | 78 private: |
78 static const char *kHome; | 79 static const char* kHome; |
79 static const char *kClearLine; | 80 static const char* kClearLine; |
80 static const char *kUp; | 81 static const char* kUp; |
81 static constexpr double ns_per_second = 1000000000.0; | 82 static constexpr double ns_per_second = 1000000000.0; |
82 | 83 |
83 // Processes arguments. | 84 // Processes arguments. |
84 void ProcessArgs(const std::vector<std::string>& args) { | 85 void ProcessArgs(const std::vector<std::string>& args) { |
85 for (size_t i = 1; i < args.size(); ++i) { | 86 for (size_t i = 1; i < args.size(); ++i) { |
86 const std::string& arg = args[i]; | 87 const std::string& arg = args[i]; |
87 if (arg == "--paint") { | 88 if (arg == "--paint") { |
88 paint_ = true; | 89 paint_ = true; |
89 } else if (arg == "--no-paint") { | 90 } else if (arg == "--no-paint") { |
90 paint_ = false; | 91 paint_ = false; |
91 } else { | 92 } else { |
92 input_file_names_.push_back(arg); | 93 input_file_names_.push_back(arg); |
93 } | 94 } |
94 } | 95 } |
95 | 96 |
96 input_file_names_iter_ = input_file_names_.begin(); | 97 input_file_names_iter_ = input_file_names_.begin(); |
97 } | 98 } |
98 | 99 |
99 // Creates a new MediaTest object to play the file referenced by | 100 // Creates a new MediaTest object to play the file referenced by |
100 // input_file_names_iter_. | 101 // input_file_names_iter_. |
101 void CreateNewMediaTest() { | 102 void CreateNewMediaTest() { |
102 MOJO_DCHECK(input_file_names_iter_ != input_file_names_.end()); | 103 MOJO_DCHECK(input_file_names_iter_ != input_file_names_.end()); |
103 media_test_ = MediaTest::Create(app_, *input_file_names_iter_); | 104 media_test_ = MediaTest::Create(app_, *input_file_names_iter_); |
104 | 105 |
105 metadata_shown_ = false; | 106 metadata_shown_ = false; |
106 media_test_->RegisterUpdateCallback([this]() { | 107 media_test_->RegisterUpdateCallback( |
107 HandleMediaTestUpdateCallback(); | 108 [this]() { HandleMediaTestUpdateCallback(); }); |
108 }); | |
109 | 109 |
110 media_test_->Play(); | 110 media_test_->Play(); |
111 } | 111 } |
112 | 112 |
113 void HandleMediaTestUpdateCallback() { | 113 void HandleMediaTestUpdateCallback() { |
114 if (media_test_->state() == MediaState::ENDED) { | 114 if (media_test_->state() == MediaState::ENDED) { |
115 // MediaTest doesn't appreciate being deleted in this callback. | 115 // MediaTest doesn't appreciate being deleted in this callback. |
116 // Next time Poll runs, we move on to the next file. | 116 // Next time Poll runs, we move on to the next file. |
117 base::MessageLoop::current()->PostTask( | 117 base::MessageLoop::current()->PostTask( |
118 FROM_HERE, | 118 FROM_HERE, |
119 base::Bind(&MediaTestApp::PlayNext, base::Unretained(this))); | 119 base::Bind(&MediaTestApp::PlayNext, base::Unretained(this))); |
120 } | 120 } |
121 | 121 |
122 const MediaMetadataPtr& metadata = media_test_->metadata(); | 122 const MediaMetadataPtr& metadata = media_test_->metadata(); |
123 | 123 |
124 if (metadata) { | 124 if (metadata) { |
125 duration_ns_ = metadata->duration; | 125 duration_ns_ = metadata->duration; |
126 } | 126 } |
127 | 127 |
128 if (paint_) { | 128 if (paint_) { |
129 // Move the cursor up the terminal so we paint over the old metadata | 129 // Move the cursor up the terminal so we paint over the old metadata |
130 // (7 lines) a blank line and the state line (total of 9 lines). | 130 // (7 lines) a blank line and the state line (total of 9 lines). |
131 std::cout << kHome | 131 std::cout << kHome << kUp << kUp << kUp << kUp << kUp << kUp << kUp << kUp |
132 << kUp << kUp << kUp << kUp << kUp << kUp << kUp << kUp << kUp; | 132 << kUp; |
133 } | 133 } |
134 | 134 |
135 if (!paint_ && metadata_shown_) { | 135 if (!paint_ && metadata_shown_) { |
136 // Do nothing. | 136 // Do nothing. |
137 } else if (metadata) { | 137 } else if (metadata) { |
138 metadata_shown_ = true; | 138 metadata_shown_ = true; |
139 std::cout << " duration " << std::setprecision(1) << | 139 std::cout << " duration " << std::setprecision(1) |
140 double(metadata->duration) / ns_per_second << " seconds" | 140 << double(metadata->duration) / ns_per_second << " seconds" |
141 << clear_line() << std::endl; | 141 << clear_line() << std::endl; |
142 std::cout << " title " << | 142 std::cout << " title " |
143 (metadata->title ? metadata->title : "<none>") | 143 << (metadata->title ? metadata->title : "<none>") |
144 << clear_line() << std::endl; | 144 << clear_line() << std::endl; |
145 std::cout << " artist " << | 145 std::cout << " artist " |
146 (metadata->artist ? metadata->artist : "<none>") | 146 << (metadata->artist ? metadata->artist : "<none>") |
147 << clear_line() << std::endl; | 147 << clear_line() << std::endl; |
148 std::cout << " album " << | 148 std::cout << " album " |
149 (metadata->album ? metadata->album : "<none>") | 149 << (metadata->album ? metadata->album : "<none>") |
150 << clear_line() << std::endl; | 150 << clear_line() << std::endl; |
151 std::cout << " publisher " << | 151 std::cout << " publisher " |
152 (metadata->publisher ? metadata->publisher : "<none>") | 152 << (metadata->publisher ? metadata->publisher : "<none>") |
153 << clear_line() << std::endl; | 153 << clear_line() << std::endl; |
154 std::cout << " genre " << | 154 std::cout << " genre " |
155 (metadata->genre ? metadata->genre : "<none>") | 155 << (metadata->genre ? metadata->genre : "<none>") |
156 << clear_line() << std::endl; | 156 << clear_line() << std::endl; |
157 std::cout << " composer " << | 157 std::cout << " composer " |
158 (metadata->composer ? metadata->composer : "<none>") | 158 << (metadata->composer ? metadata->composer : "<none>") |
159 << clear_line() << std::endl << std::endl; | 159 << clear_line() << std::endl |
| 160 << std::endl; |
160 } else { | 161 } else { |
161 std::cout << " duration <none>" << kClearLine << std::endl; | 162 std::cout << " duration <none>" << kClearLine << std::endl; |
162 std::cout << " title <none>" << kClearLine << std::endl; | 163 std::cout << " title <none>" << kClearLine << std::endl; |
163 std::cout << " artist <none>" << kClearLine << std::endl; | 164 std::cout << " artist <none>" << kClearLine << std::endl; |
164 std::cout << " album <none>" << kClearLine << std::endl; | 165 std::cout << " album <none>" << kClearLine << std::endl; |
165 std::cout << " publisher <none>" << kClearLine << std::endl; | 166 std::cout << " publisher <none>" << kClearLine << std::endl; |
166 std::cout << " genre <none>" << kClearLine << std::endl; | 167 std::cout << " genre <none>" << kClearLine << std::endl; |
167 std::cout << " composer <none>" << kClearLine << std::endl; | 168 std::cout << " composer <none>" << kClearLine << std::endl; |
168 std::cout << std::endl; | 169 std::cout << std::endl; |
169 } | 170 } |
(...skipping 21 matching lines...) Loading... |
191 void HandleKeystroke(char keystroke) { | 192 void HandleKeystroke(char keystroke) { |
192 switch (keystroke) { | 193 switch (keystroke) { |
193 case '\n': | 194 case '\n': |
194 TogglePlayPause(); | 195 TogglePlayPause(); |
195 break; | 196 break; |
196 case 'q': | 197 case 'q': |
197 base::MessageLoop::current()->Quit(); | 198 base::MessageLoop::current()->Quit(); |
198 quit_ = true; | 199 quit_ = true; |
199 if (paint_) { | 200 if (paint_) { |
200 std::cout << kHome << kUp << " quitting" << kClearLine << std::endl | 201 std::cout << kHome << kUp << " quitting" << kClearLine << std::endl |
201 << kClearLine << std::endl; | 202 << kClearLine << std::endl; |
202 } else { | 203 } else { |
203 std::cout << " quitting" << std::endl; | 204 std::cout << " quitting" << std::endl; |
204 } | 205 } |
205 break; | 206 break; |
206 case 'n': | 207 case 'n': |
207 if (++input_file_names_iter_ == input_file_names_.end()) { | 208 if (++input_file_names_iter_ == input_file_names_.end()) { |
208 input_file_names_iter_ = input_file_names_.begin(); | 209 input_file_names_iter_ = input_file_names_.begin(); |
209 } | 210 } |
210 CreateNewMediaTest(); | 211 CreateNewMediaTest(); |
211 break; | 212 break; |
(...skipping 11 matching lines...) Loading... |
223 case '4': | 224 case '4': |
224 case '5': | 225 case '5': |
225 case '6': | 226 case '6': |
226 case '7': | 227 case '7': |
227 case '8': | 228 case '8': |
228 case '9': { | 229 case '9': { |
229 int64_t position_ns = ((keystroke - '0') / 10.0) * duration_ns_; | 230 int64_t position_ns = ((keystroke - '0') / 10.0) * duration_ns_; |
230 media_test_->Seek(position_ns); | 231 media_test_->Seek(position_ns); |
231 if (!paint_) { | 232 if (!paint_) { |
232 std::cout << " seeking to " << std::fixed << std::setprecision(1) | 233 std::cout << " seeking to " << std::fixed << std::setprecision(1) |
233 << double(position_ns) / ns_per_second | 234 << double(position_ns) / ns_per_second << " seconds " |
234 << " seconds " << std::endl; | 235 << std::endl; |
235 } | 236 } |
236 break; | 237 break; |
237 } | 238 } |
238 } | 239 } |
239 } | 240 } |
240 | 241 |
241 // Toggles between play and pause (prepared) states. | 242 // Toggles between play and pause (prepared) states. |
242 void TogglePlayPause() { | 243 void TogglePlayPause() { |
243 switch (media_test_->state()) { | 244 switch (media_test_->state()) { |
244 case MediaState::PAUSED: | 245 case MediaState::PAUSED: |
(...skipping 31 matching lines...) Loading... |
276 // Eat the any additional keystrokes, which would otherwise make it to the | 277 // Eat the any additional keystrokes, which would otherwise make it to the |
277 // command shell. | 278 // command shell. |
278 while (Keystroke() != 0) { | 279 while (Keystroke() != 0) { |
279 // Do nothing. | 280 // Do nothing. |
280 } | 281 } |
281 return; | 282 return; |
282 } | 283 } |
283 | 284 |
284 if (paint_) { | 285 if (paint_) { |
285 std::cout << kHome << " " << std::fixed << std::setprecision(1) | 286 std::cout << kHome << " " << std::fixed << std::setprecision(1) |
286 << double(media_test_->position_ns()) / ns_per_second | 287 << double(media_test_->position_ns()) / ns_per_second |
287 << " seconds " << kClearLine << std::flush; | 288 << " seconds " << kClearLine << std::flush; |
288 } | 289 } |
289 | 290 |
290 base::MessageLoop::current()->PostDelayedTask( | 291 base::MessageLoop::current()->PostDelayedTask( |
291 FROM_HERE, | 292 FROM_HERE, base::Bind(&MediaTestApp::Poll, base::Unretained(this)), |
292 base::Bind(&MediaTestApp::Poll, base::Unretained(this)), | |
293 base::TimeDelta::FromMilliseconds(100)); | 293 base::TimeDelta::FromMilliseconds(100)); |
294 } | 294 } |
295 | 295 |
296 void PlayNext() { | 296 void PlayNext() { |
297 if (++input_file_names_iter_ == input_file_names_.end()) { | 297 if (++input_file_names_iter_ == input_file_names_.end()) { |
298 input_file_names_iter_ = input_file_names_.begin(); | 298 input_file_names_iter_ = input_file_names_.begin(); |
299 } else { | 299 } else { |
300 CreateNewMediaTest(); | 300 CreateNewMediaTest(); |
301 } | 301 } |
302 } | 302 } |
303 | 303 |
304 const char* clear_line() const { | 304 const char* clear_line() const { return paint_ ? kClearLine : ""; } |
305 return paint_ ? kClearLine : ""; | |
306 } | |
307 | 305 |
308 mojo::ApplicationImpl* app_; | 306 mojo::ApplicationImpl* app_; |
309 std::unique_ptr<MediaTest> media_test_; | 307 std::unique_ptr<MediaTest> media_test_; |
310 std::deque<std::string> input_file_names_; | 308 std::deque<std::string> input_file_names_; |
311 decltype(input_file_names_.begin()) input_file_names_iter_; | 309 decltype(input_file_names_.begin()) input_file_names_iter_; |
312 bool quit_ = false; | 310 bool quit_ = false; |
313 bool paint_ = true; | 311 bool paint_ = true; |
314 bool metadata_shown_ = false; | 312 bool metadata_shown_ = false; |
315 uint64_t duration_ns_; | 313 uint64_t duration_ns_; |
316 | 314 |
317 DISALLOW_COPY_AND_ASSIGN(MediaTestApp); | 315 DISALLOW_COPY_AND_ASSIGN(MediaTestApp); |
318 }; | 316 }; |
319 | 317 |
320 const char* MediaTestApp::kHome = "\r"; | 318 const char* MediaTestApp::kHome = "\r"; |
321 const char* MediaTestApp::kClearLine = "\033[K"; | 319 const char* MediaTestApp::kClearLine = "\033[K"; |
322 const char* MediaTestApp::kUp = "\033[A"; | 320 const char* MediaTestApp::kUp = "\033[A"; |
323 | 321 |
324 } // namespace examples | 322 } // namespace examples |
325 } // namespace media | 323 } // namespace media |
326 } // namespace mojo | 324 } // namespace mojo |
327 | 325 |
328 MojoResult MojoMain(MojoHandle application_request) { | 326 MojoResult MojoMain(MojoHandle application_request) { |
329 mojo::ApplicationRunnerChromium | 327 mojo::ApplicationRunnerChromium runner( |
330 runner(new mojo::media::examples::MediaTestApp); | 328 new mojo::media::examples::MediaTestApp); |
331 return runner.Run(application_request); | 329 return runner.Run(application_request); |
332 } | 330 } |
OLD | NEW |