source: smplayer/vendor/current/src/mplayerprocess.cpp

Last change on this file was 186, checked in by Silvan Scherrer, 8 years ago

SMPlayer: update vendor to 17.1.0

File size: 25.1 KB
Line 
1/* smplayer, GUI front-end for mplayer.
2 Copyright (C) 2006-2017 Ricardo Villalba <rvm@users.sourceforge.net>
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17*/
18
19#include "mplayerprocess.h"
20#include <QRegExp>
21#include <QStringList>
22#include <QApplication>
23
24#include "global.h"
25#include "preferences.h"
26#include "mplayerversion.h"
27#include "colorutils.h"
28
29using namespace Global;
30
31#define TOO_CHAPTERS_WORKAROUND
32
33MplayerProcess::MplayerProcess(QObject * parent)
34 : PlayerProcess(parent)
35 , notified_mplayer_is_running(false)
36 , received_end_of_file(false)
37 , last_sub_id(-1)
38 , mplayer_svn(-1) // Not found yet
39#if NOTIFY_SUB_CHANGES
40 , subtitle_info_received(false)
41 , subtitle_info_changed(false)
42#endif
43#if NOTIFY_AUDIO_CHANGES
44 , audio_info_changed(false)
45#endif
46 , dvd_current_title(-1)
47 , br_current_title(-1)
48{
49 player_id = PlayerID::MPLAYER;
50
51 connect( this, SIGNAL(lineAvailable(QByteArray)),
52 this, SLOT(parseLine(QByteArray)) );
53
54 connect( this, SIGNAL(finished(int,QProcess::ExitStatus)),
55 this, SLOT(processFinished(int,QProcess::ExitStatus)) );
56
57 connect( this, SIGNAL(error(QProcess::ProcessError)),
58 this, SLOT(gotError(QProcess::ProcessError)) );
59}
60
61MplayerProcess::~MplayerProcess() {
62}
63
64bool MplayerProcess::start() {
65 md.reset();
66 notified_mplayer_is_running = false;
67 last_sub_id = -1;
68 mplayer_svn = -1; // Not found yet
69 received_end_of_file = false;
70
71#if NOTIFY_SUB_CHANGES
72 subs.clear();
73 subtitle_info_received = false;
74 subtitle_info_changed = false;
75#endif
76
77#if NOTIFY_AUDIO_CHANGES
78 audios.clear();
79 audio_info_changed = false;
80#endif
81
82 dvd_current_title = -1;
83 br_current_title = -1;
84
85 MyProcess::start();
86
87 return waitForStarted();
88}
89
90
91static QRegExp rx_av("^[AV]: *([0-9,:.-]+)");
92static QRegExp rx_frame("^[AV]:.* (\\d+)\\/.\\d+");// [0-9,.]+");
93static QRegExp rx("^(.*)=(.*)");
94#if !NOTIFY_AUDIO_CHANGES
95static QRegExp rx_audio_mat("^ID_AID_(\\d+)_(LANG|NAME)=(.*)");
96#endif
97static QRegExp rx_video("^ID_VID_(\\d+)_(LANG|NAME)=(.*)");
98static QRegExp rx_title("^ID_(DVD|BLURAY)_TITLE_(\\d+)_(LENGTH|CHAPTERS|ANGLES)=(.*)");
99static QRegExp rx_chapters("^ID_CHAPTER_(\\d+)_(START|END|NAME)=(.+)");
100static QRegExp rx_winresolution("^VO: \\[(.*)\\] (\\d+)x(\\d+) => (\\d+)x(\\d+)");
101static QRegExp rx_ao("^AO: \\[(.*)\\]");
102static QRegExp rx_paused("^ID_PAUSED");
103#if !CHECK_VIDEO_CODEC_FOR_NO_VIDEO
104static QRegExp rx_novideo("^Video: no video");
105#endif
106static QRegExp rx_cache("^Cache fill:.*");
107static QRegExp rx_cache_empty("^Cache empty.*|^Cache not filling.*");
108static QRegExp rx_create_index("^Generating Index:.*");
109static QRegExp rx_play("^Starting playback...");
110static QRegExp rx_connecting("^Connecting to .*");
111static QRegExp rx_resolving("^Resolving .*");
112static QRegExp rx_screenshot("^\\*\\*\\* screenshot '(.*)'");
113static QRegExp rx_endoffile("^Exiting... \\(End of file\\)|^ID_EXIT=EOF");
114static QRegExp rx_mkvchapters("\\[mkv\\] Chapter (\\d+) from");
115static QRegExp rx_aspect2("^Movie-Aspect is ([0-9,.]+):1");
116static QRegExp rx_fontcache("^\\[ass\\] Updating font cache|^\\[ass\\] Init");
117static QRegExp rx_scanning_font("Scanning file");
118static QRegExp rx_forbidden("Server returned 403: Forbidden");
119#if DVDNAV_SUPPORT
120static QRegExp rx_dvdnav_switch_title("^DVDNAV, switched to title: (\\d+)");
121static QRegExp rx_dvdnav_length("^ANS_length=(.*)");
122static QRegExp rx_dvdnav_title_is_menu("^DVDNAV_TITLE_IS_MENU");
123static QRegExp rx_dvdnav_title_is_movie("^DVDNAV_TITLE_IS_MOVIE");
124#endif
125
126// VCD
127static QRegExp rx_vcd("^ID_VCD_TRACK_(\\d+)_MSF=(.*)");
128
129// Audio CD
130static QRegExp rx_cdda("^ID_CDDA_TRACK_(\\d+)_MSF=(.*)");
131
132//Subtitles
133static QRegExp rx_subtitle("^ID_(SUBTITLE|FILE_SUB|VOBSUB)_ID=(\\d+)");
134static QRegExp rx_sid("^ID_(SID|VSID)_(\\d+)_(LANG|NAME)=(.*)");
135static QRegExp rx_subtitle_file("^ID_FILE_SUB_FILENAME=(.*)");
136
137// Audio
138#if NOTIFY_AUDIO_CHANGES
139static QRegExp rx_audio("^ID_AUDIO_ID=(\\d+)");
140static QRegExp rx_audio_info("^ID_AID_(\\d+)_(LANG|NAME)=(.*)");
141#endif
142
143#if PROGRAM_SWITCH
144static QRegExp rx_program("^PROGRAM_ID=(\\d+)");
145#endif
146
147//Clip info
148static QRegExp rx_clip_name("^ (name|title): (.*)", Qt::CaseInsensitive);
149static QRegExp rx_clip_artist("^ artist: (.*)", Qt::CaseInsensitive);
150static QRegExp rx_clip_author("^ author: (.*)", Qt::CaseInsensitive);
151static QRegExp rx_clip_album("^ album: (.*)", Qt::CaseInsensitive);
152static QRegExp rx_clip_genre("^ genre: (.*)", Qt::CaseInsensitive);
153static QRegExp rx_clip_date("^ (creation date|year): (.*)", Qt::CaseInsensitive);
154static QRegExp rx_clip_track("^ track: (.*)", Qt::CaseInsensitive);
155static QRegExp rx_clip_copyright("^ copyright: (.*)", Qt::CaseInsensitive);
156static QRegExp rx_clip_comment("^ comment: (.*)", Qt::CaseInsensitive);
157static QRegExp rx_clip_software("^ software: (.*)", Qt::CaseInsensitive);
158
159static QRegExp rx_stream_title("^.* StreamTitle='(.*)';");
160static QRegExp rx_stream_title_and_url("^.* StreamTitle='(.*)';StreamUrl='(.*)';");
161
162
163void MplayerProcess::parseLine(QByteArray ba) {
164 //qDebug("MplayerProcess::parseLine: '%s'", ba.data() );
165
166 QString tag;
167 QString value;
168
169#if COLOR_OUTPUT_SUPPORT
170 QString line = ColorUtils::stripColorsTags(QString::fromLocal8Bit(ba));
171#else
172 #ifdef Q_OS_WIN
173 QString line = QString::fromUtf8(ba);
174 #else
175 QString line = QString::fromLocal8Bit(ba);
176 #endif
177#endif
178
179 // Parse A: V: line
180 //qDebug("%s", line.toUtf8().data());
181 if (rx_av.indexIn(line) > -1) {
182 double sec = rx_av.cap(1).toDouble();
183 //qDebug("cap(1): '%s'", rx_av.cap(1).toUtf8().data() );
184 //qDebug("sec: %f", sec);
185
186#if NOTIFY_SUB_CHANGES
187 if (notified_mplayer_is_running) {
188 if (subtitle_info_changed) {
189 qDebug("MplayerProcess::parseLine: subtitle_info_changed");
190 subtitle_info_changed = false;
191 subtitle_info_received = false;
192 emit subtitleInfoChanged(subs);
193 }
194 if (subtitle_info_received) {
195 qDebug("MplayerProcess::parseLine: subtitle_info_received");
196 subtitle_info_received = false;
197 emit subtitleInfoReceivedAgain(subs);
198 }
199 }
200#endif
201
202#if NOTIFY_AUDIO_CHANGES
203 if (notified_mplayer_is_running) {
204 if (audio_info_changed) {
205 qDebug("MplayerProcess::parseLine: audio_info_changed");
206 audio_info_changed = false;
207 emit audioInfoChanged(audios);
208 }
209 }
210#endif
211
212 if (!notified_mplayer_is_running) {
213 qDebug("MplayerProcess::parseLine: starting sec: %f", sec);
214 if ( (md.n_chapters <= 0) && (dvd_current_title > 0) &&
215 (md.titles.find(dvd_current_title) != -1) )
216 {
217 int idx = md.titles.find(dvd_current_title);
218 md.n_chapters = md.titles.itemAt(idx).chapters();
219 qDebug("MplayerProcess::parseLine: setting chapters to %d", md.n_chapters);
220 }
221
222#if CHECK_VIDEO_CODEC_FOR_NO_VIDEO
223 // Another way to find out if there's no video
224 if (md.video_codec.isEmpty()) {
225 md.novideo = true;
226 emit receivedNoVideo();
227 }
228#endif
229
230 emit receivedStartingTime(sec);
231 emit mplayerFullyLoaded();
232
233 emit receivedCurrentFrame(0); // Ugly hack: set the frame counter to 0
234
235 notified_mplayer_is_running = true;
236 }
237
238 emit receivedCurrentSec( sec );
239
240 // Check for frame
241 if (rx_frame.indexIn(line) > -1) {
242 int frame = rx_frame.cap(1).toInt();
243 //qDebug(" frame: %d", frame);
244 emit receivedCurrentFrame(frame);
245 }
246 }
247 else {
248 // Emulates mplayer version in Ubuntu:
249 //if (line.startsWith("MPlayer 1.0rc1")) line = "MPlayer 2:1.0~rc1-0ubuntu13.1 (C) 2000-2006 MPlayer Team";
250 //if (line.startsWith("MPlayer2")) line = "mplayer2 d0305da (C) 2000-2012 MPlayer & mplayer2 teams";
251 //if (line.startsWith("MPlayer SVN")) line = "MPlayer svn r34540 (Ubuntu), built with gcc-4.6 (C) 2000-2012 MPlayer Team";
252 //if (line.startsWith("MPlayer SVN")) line = "MPlayer 1.2-4.8 (C) 2000-2015 MPlayer Team";
253
254 // Emulates unknown version
255 //if (line.startsWith("MPlayer SVN")) line = "MPlayer lalksklsjjakksja";
256
257 emit lineAvailable(line);
258
259 // Parse other things
260 qDebug("MplayerProcess::parseLine: '%s'", line.toUtf8().data() );
261
262 // Screenshot
263 if (rx_screenshot.indexIn(line) > -1) {
264 QString shot = rx_screenshot.cap(1);
265 qDebug("MplayerProcess::parseLine: screenshot: '%s'", shot.toUtf8().data());
266 emit receivedScreenshot( shot );
267 }
268 else
269
270 // End of file
271 if (rx_endoffile.indexIn(line) > -1) {
272 qDebug("MplayerProcess::parseLine: detected end of file");
273 if (!received_end_of_file) {
274 // In case of playing VCDs or DVDs, maybe the first title
275 // is not playable, so the GUI doesn't get the info about
276 // available titles. So if we received the end of file
277 // first let's pretend the file has started so the GUI can have
278 // the data.
279 if ( !notified_mplayer_is_running) {
280 emit mplayerFullyLoaded();
281 }
282
283 //emit receivedEndOfFile();
284 // Send signal once the process is finished, not now!
285 received_end_of_file = true;
286 }
287 }
288 else
289
290 // Window resolution
291 if (rx_winresolution.indexIn(line) > -1) {
292 /*
293 md.win_width = rx_winresolution.cap(4).toInt();
294 md.win_height = rx_winresolution.cap(5).toInt();
295 md.video_aspect = (double) md.win_width / md.win_height;
296 */
297
298 int w = rx_winresolution.cap(4).toInt();
299 int h = rx_winresolution.cap(5).toInt();
300
301 emit receivedVO( rx_winresolution.cap(1) );
302 emit receivedWindowResolution( w, h );
303 //emit mplayerFullyLoaded();
304 }
305 else
306
307#if !CHECK_VIDEO_CODEC_FOR_NO_VIDEO
308 // No video
309 if (rx_novideo.indexIn(line) > -1) {
310 md.novideo = true;
311 emit receivedNoVideo();
312 //emit mplayerFullyLoaded();
313 }
314 else
315#endif
316
317 // Pause
318 if (rx_paused.indexIn(line) > -1) {
319 emit receivedPause();
320 }
321
322 // Stream title
323 if (rx_stream_title_and_url.indexIn(line) > -1) {
324 QString s = rx_stream_title_and_url.cap(1);
325 QString url = rx_stream_title_and_url.cap(2);
326 qDebug("MplayerProcess::parseLine: stream_title: '%s'", s.toUtf8().data());
327 qDebug("MplayerProcess::parseLine: stream_url: '%s'", url.toUtf8().data());
328 md.stream_title = s;
329 md.stream_url = url;
330 emit receivedStreamTitleAndUrl( s, url );
331 }
332 else
333 if (rx_stream_title.indexIn(line) > -1) {
334 QString s = rx_stream_title.cap(1);
335 qDebug("MplayerProcess::parseLine: stream_title: '%s'", s.toUtf8().data());
336 md.stream_title = s;
337 emit receivedStreamTitle( s );
338 }
339
340#if NOTIFY_SUB_CHANGES
341 // Subtitles
342 if ((rx_subtitle.indexIn(line) > -1) || (rx_sid.indexIn(line) > -1) || (rx_subtitle_file.indexIn(line) > -1)) {
343 int r = subs.parse(line);
344 //qDebug("MplayerProcess::parseLine: result of parse: %d", r);
345 subtitle_info_received = true;
346 if ((r == SubTracks::SubtitleAdded) || (r == SubTracks::SubtitleChanged)) subtitle_info_changed = true;
347 }
348#endif
349
350#if NOTIFY_AUDIO_CHANGES
351 // Audio
352 if (rx_audio.indexIn(line) > -1) {
353 int ID = rx_audio.cap(1).toInt();
354 qDebug("MplayerProcess::parseLine: ID_AUDIO_ID: %d", ID);
355 if (audios.find(ID) == -1) audio_info_changed = true;
356 audios.addID( ID );
357 }
358
359 if (rx_audio_info.indexIn(line) > -1) {
360 int ID = rx_audio_info.cap(1).toInt();
361 QString lang = rx_audio_info.cap(3);
362 QString t = rx_audio_info.cap(2);
363 qDebug("MplayerProcess::parseLine: Audio: ID: %d, Lang: '%s' Type: '%s'",
364 ID, lang.toUtf8().data(), t.toUtf8().data());
365
366 int idx = audios.find(ID);
367 if (idx == -1) {
368 qDebug("MplayerProcess::parseLine: audio %d doesn't exist, adding it", ID);
369
370 audio_info_changed = true;
371 if ( t == "NAME" )
372 audios.addName(ID, lang);
373 else
374 audios.addLang(ID, lang);
375 } else {
376 qDebug("MplayerProcess::parseLine: audio %d exists, modifying it", ID);
377
378 if (t == "NAME") {
379 //qDebug("MplayerProcess::parseLine: name of audio %d: %s", ID, audios.itemAt(idx).name().toUtf8().constData());
380 if (audios.itemAt(idx).name() != lang) {
381 audio_info_changed = true;
382 audios.addName(ID, lang);
383 }
384 } else {
385 //qDebug("MplayerProcess::parseLine: language of audio %d: %s", ID, audios.itemAt(idx).lang().toUtf8().constData());
386 if (audios.itemAt(idx).lang() != lang) {
387 audio_info_changed = true;
388 audios.addLang(ID, lang);
389 }
390 }
391 }
392 }
393#endif
394
395#if DVDNAV_SUPPORT
396 if (rx_dvdnav_switch_title.indexIn(line) > -1) {
397 int title = rx_dvdnav_switch_title.cap(1).toInt();
398 qDebug("MplayerProcess::parseLine: dvd title: %d", title);
399 emit receivedDVDTitle(title);
400 }
401 if (rx_dvdnav_length.indexIn(line) > -1) {
402 double length = rx_dvdnav_length.cap(1).toDouble();
403 qDebug("MplayerProcess::parseLine: length: %f", length);
404 if (length != md.duration) {
405 md.duration = length;
406 emit receivedDuration(length);
407 }
408 }
409 if (rx_dvdnav_title_is_menu.indexIn(line) > -1) {
410 emit receivedTitleIsMenu();
411 }
412 if (rx_dvdnav_title_is_movie.indexIn(line) > -1) {
413 emit receivedTitleIsMovie();
414 }
415#endif
416
417 if (rx_cache_empty.indexIn(line) > -1) {
418 emit receivedCacheEmptyMessage(line);
419 }
420
421 // The following things are not sent when the file has started to play
422 // (or if sent, smplayer will ignore anyway...)
423 // So not process anymore, if video is playing to save some time
424 if (notified_mplayer_is_running) {
425 return;
426 }
427
428 if ( (mplayer_svn == -1) && ((line.startsWith("MPlayer ")) || (line.startsWith("MPlayer2 ", Qt::CaseInsensitive))) ) {
429 mplayer_svn = MplayerVersion::mplayerVersion(line);
430 qDebug("MplayerProcess::parseLine: MPlayer SVN: %d", mplayer_svn);
431 if (mplayer_svn <= 0) {
432 qWarning("MplayerProcess::parseLine: couldn't parse mplayer version!");
433 emit failedToParseMplayerVersion(line);
434 }
435 }
436
437#if !NOTIFY_SUB_CHANGES
438 // Subtitles
439 if (rx_subtitle.indexIn(line) > -1) {
440 md.subs.parse(line);
441 }
442 else
443 if (rx_sid.indexIn(line) > -1) {
444 md.subs.parse(line);
445 }
446 else
447 if (rx_subtitle_file.indexIn(line) > -1) {
448 md.subs.parse(line);
449 }
450#endif
451 // AO
452 if (rx_ao.indexIn(line) > -1) {
453 emit receivedAO( rx_ao.cap(1) );
454 }
455 else
456
457#if !NOTIFY_AUDIO_CHANGES
458 // Matroska audio
459 if (rx_audio_mat.indexIn(line) > -1) {
460 int ID = rx_audio_mat.cap(1).toInt();
461 QString lang = rx_audio_mat.cap(3);
462 QString t = rx_audio_mat.cap(2);
463 qDebug("MplayerProcess::parseLine: Audio: ID: %d, Lang: '%s' Type: '%s'",
464 ID, lang.toUtf8().data(), t.toUtf8().data());
465
466 if ( t == "NAME" )
467 md.audios.addName(ID, lang);
468 else
469 md.audios.addLang(ID, lang);
470 }
471 else
472#endif
473
474#if PROGRAM_SWITCH
475 // Program
476 if (rx_program.indexIn(line) > -1) {
477 int ID = rx_program.cap(1).toInt();
478 qDebug("MplayerProcess::parseLine: Program: ID: %d", ID);
479 md.programs.addID( ID );
480 }
481 else
482#endif
483
484 // Video tracks
485 if (rx_video.indexIn(line) > -1) {
486 int ID = rx_video.cap(1).toInt();
487 QString lang = rx_video.cap(3);
488 QString t = rx_video.cap(2);
489 qDebug("MplayerProcess::parseLine: Video: ID: %d, Lang: '%s' Type: '%s'",
490 ID, lang.toUtf8().data(), t.toUtf8().data());
491
492 if ( t == "NAME" )
493 md.videos.addName(ID, lang);
494 else
495 md.videos.addLang(ID, lang);
496 }
497 else
498
499 // Matroshka chapters
500 if (rx_mkvchapters.indexIn(line)!=-1) {
501 int c = rx_mkvchapters.cap(1).toInt();
502 qDebug("MplayerProcess::parseLine: mkv chapters: %d", c);
503 if ((c+1) > md.n_chapters) {
504 md.n_chapters = c+1;
505 qDebug("MplayerProcess::parseLine: chapters set to: %d", md.n_chapters);
506 }
507 }
508 else
509 // Chapter info
510 if (rx_chapters.indexIn(line) > -1) {
511 int const chap_ID = rx_chapters.cap(1).toInt();
512 QString const chap_type = rx_chapters.cap(2);
513 QString const chap_value = rx_chapters.cap(3);
514 double const chap_value_d = chap_value.toDouble();
515
516 if(!chap_type.compare("START"))
517 {
518 md.chapters.addStart(chap_ID, chap_value_d/1000);
519 qDebug("MplayerProcess::parseLine: Chapter (ID: %d) starts at: %g",chap_ID, chap_value_d/1000);
520 }
521 else if(!chap_type.compare("END"))
522 {
523 md.chapters.addEnd(chap_ID, chap_value_d/1000);
524 qDebug("MplayerProcess::parseLine: Chapter (ID: %d) ends at: %g",chap_ID, chap_value_d/1000);
525 }
526 else if(!chap_type.compare("NAME"))
527 {
528 md.chapters.addName(chap_ID, chap_value);
529 qDebug("MplayerProcess::parseLine: Chapter (ID: %d) name: %s",chap_ID, chap_value.toUtf8().data());
530 }
531 }
532 else
533
534 // VCD titles
535 if (rx_vcd.indexIn(line) > -1 ) {
536 int ID = rx_vcd.cap(1).toInt();
537 QString length = rx_vcd.cap(2);
538 //md.titles.addID( ID );
539 md.titles.addName( ID, length );
540 }
541 else
542
543 // Audio CD titles
544 if (rx_cdda.indexIn(line) > -1 ) {
545 int ID = rx_cdda.cap(1).toInt();
546 QString length = rx_cdda.cap(2);
547 double duration = 0;
548 QRegExp r("(\\d+):(\\d+):(\\d+)");
549 if ( r.indexIn(length) > -1 ) {
550 duration = r.cap(1).toInt() * 60;
551 duration += r.cap(2).toInt();
552 }
553 md.titles.addID( ID );
554 /*
555 QString name = QString::number(ID) + " (" + length + ")";
556 md.titles.addName( ID, name );
557 */
558 md.titles.addDuration( ID, duration );
559 }
560 else
561
562 // DVD/Bluray titles
563 if (rx_title.indexIn(line) > -1) {
564 int ID = rx_title.cap(2).toInt();
565 QString t = rx_title.cap(3);
566
567 if (t=="LENGTH") {
568 double length = rx_title.cap(4).toDouble();
569 qDebug("MplayerProcess::parseLine: Title: ID: %d, Length: '%f'", ID, length);
570 md.titles.addDuration(ID, length);
571 }
572 else
573 if (t=="CHAPTERS") {
574 int chapters = rx_title.cap(4).toInt();
575 qDebug("MplayerProcess::parseLine: Title: ID: %d, Chapters: '%d'", ID, chapters);
576 md.titles.addChapters(ID, chapters);
577 }
578 else
579 if (t=="ANGLES") {
580 int angles = rx_title.cap(4).toInt();
581 qDebug("MplayerProcess::parseLine: Title: ID: %d, Angles: '%d'", ID, angles);
582 md.titles.addAngles(ID, angles);
583 }
584 }
585 else
586
587 // Catch cache messages
588 if (rx_cache.indexIn(line) > -1) {
589 emit receivedCacheMessage(line);
590 }
591 else
592
593 // Creating index
594 if (rx_create_index.indexIn(line) > -1) {
595 emit receivedCreatingIndex(line);
596 }
597 else
598
599 // Catch connecting message
600 if (rx_connecting.indexIn(line) > -1) {
601 emit receivedConnectingToMessage(line);
602 }
603 else
604
605 // Catch resolving message
606 if (rx_resolving.indexIn(line) > -1) {
607 emit receivedResolvingMessage(line);
608 }
609 else
610
611 // Aspect ratio for old versions of mplayer
612 if (rx_aspect2.indexIn(line) > -1) {
613 md.video_aspect = rx_aspect2.cap(1).toDouble();
614 qDebug("MplayerProcess::parseLine: md.video_aspect set to %f", md.video_aspect);
615 }
616 else
617
618 // Clip info
619
620 //QString::trimmed() is used for removing leading and trailing whitespaces
621 //Some .mp3 files contain tags with starting and ending whitespaces
622 //Unfortunately MPlayer gives us leading and trailing whitespaces, Winamp for example doesn't show them
623
624 // Name
625 if (rx_clip_name.indexIn(line) > -1) {
626 QString s = rx_clip_name.cap(2).trimmed();
627 qDebug("MplayerProcess::parseLine: clip_name: '%s'", s.toUtf8().data());
628 md.clip_name = s;
629 }
630 else
631
632 // Artist
633 if (rx_clip_artist.indexIn(line) > -1) {
634 QString s = rx_clip_artist.cap(1).trimmed();
635 qDebug("MplayerProcess::parseLine: clip_artist: '%s'", s.toUtf8().data());
636 md.clip_artist = s;
637 }
638 else
639
640 // Author
641 if (rx_clip_author.indexIn(line) > -1) {
642 QString s = rx_clip_author.cap(1).trimmed();
643 qDebug("MplayerProcess::parseLine: clip_author: '%s'", s.toUtf8().data());
644 md.clip_author = s;
645 }
646 else
647
648 // Album
649 if (rx_clip_album.indexIn(line) > -1) {
650 QString s = rx_clip_album.cap(1).trimmed();
651 qDebug("MplayerProcess::parseLine: clip_album: '%s'", s.toUtf8().data());
652 md.clip_album = s;
653 }
654 else
655
656 // Genre
657 if (rx_clip_genre.indexIn(line) > -1) {
658 QString s = rx_clip_genre.cap(1).trimmed();
659 qDebug("MplayerProcess::parseLine: clip_genre: '%s'", s.toUtf8().data());
660 md.clip_genre = s;
661 }
662 else
663
664 // Date
665 if (rx_clip_date.indexIn(line) > -1) {
666 QString s = rx_clip_date.cap(2).trimmed();
667 qDebug("MplayerProcess::parseLine: clip_date: '%s'", s.toUtf8().data());
668 md.clip_date = s;
669 }
670 else
671
672 // Track
673 if (rx_clip_track.indexIn(line) > -1) {
674 QString s = rx_clip_track.cap(1).trimmed();
675 qDebug("MplayerProcess::parseLine: clip_track: '%s'", s.toUtf8().data());
676 md.clip_track = s;
677 }
678 else
679
680 // Copyright
681 if (rx_clip_copyright.indexIn(line) > -1) {
682 QString s = rx_clip_copyright.cap(1).trimmed();
683 qDebug("MplayerProcess::parseLine: clip_copyright: '%s'", s.toUtf8().data());
684 md.clip_copyright = s;
685 }
686 else
687
688 // Comment
689 if (rx_clip_comment.indexIn(line) > -1) {
690 QString s = rx_clip_comment.cap(1).trimmed();
691 qDebug("MplayerProcess::parseLine: clip_comment: '%s'", s.toUtf8().data());
692 md.clip_comment = s;
693 }
694 else
695
696 // Software
697 if (rx_clip_software.indexIn(line) > -1) {
698 QString s = rx_clip_software.cap(1).trimmed();
699 qDebug("MplayerProcess::parseLine: clip_software: '%s'", s.toUtf8().data());
700 md.clip_software = s;
701 }
702 else
703
704 if (rx_fontcache.indexIn(line) > -1) {
705 //qDebug("MplayerProcess::parseLine: updating font cache");
706 emit receivedUpdatingFontCache();
707 }
708 else
709 if (rx_scanning_font.indexIn(line) > -1) {
710 emit receivedScanningFont(line);
711 }
712 else
713
714 if (rx_forbidden.indexIn(line) > -1) {
715 qDebug("MplayerProcess::parseLine: 403 forbidden");
716 emit receivedForbiddenText();
717 }
718 else
719
720 // Catch starting message
721 /*
722 pos = rx_play.indexIn(line);
723 if (pos > -1) {
724 emit mplayerFullyLoaded();
725 }
726 */
727
728 //Generic things
729 if (rx.indexIn(line) > -1) {
730 tag = rx.cap(1);
731 value = rx.cap(2);
732 //qDebug("MplayerProcess::parseLine: tag: %s, value: %s", tag.toUtf8().data(), value.toUtf8().data());
733
734#if !NOTIFY_AUDIO_CHANGES
735 // Generic audio
736 if (tag == "ID_AUDIO_ID") {
737 int ID = value.toInt();
738 qDebug("MplayerProcess::parseLine: ID_AUDIO_ID: %d", ID);
739 md.audios.addID( ID );
740 }
741 else
742#endif
743
744 // Video
745 if (tag == "ID_VIDEO_ID") {
746 int ID = value.toInt();
747 qDebug("MplayerProcess::parseLine: ID_VIDEO_ID: %d", ID);
748 md.videos.addID( ID );
749 }
750 else
751 if (tag == "ID_LENGTH") {
752 md.duration = value.toDouble();
753 qDebug("MplayerProcess::parseLine: md.duration set to %f", md.duration);
754 // Use the bluray title length if duration is 0
755 if (md.duration == 0 && br_current_title != -1) {
756 int i = md.titles.find(br_current_title);
757 if (i != -1) {
758 double duration = md.titles.itemAt(i).duration();
759 qDebug("MplayerProcess::parseLine: using the br title length: %f", duration);
760 md.duration = duration;
761 }
762 }
763 }
764 else
765 if (tag == "ID_VIDEO_WIDTH") {
766 md.video_width = value.toInt();
767 qDebug("MplayerProcess::parseLine: md.video_width set to %d", md.video_width);
768 }
769 else
770 if (tag == "ID_VIDEO_HEIGHT") {
771 md.video_height = value.toInt();
772 qDebug("MplayerProcess::parseLine: md.video_height set to %d", md.video_height);
773 }
774 else
775 if (tag == "ID_VIDEO_ASPECT") {
776 md.video_aspect = value.toDouble();
777 if ( md.video_aspect == 0.0 ) {
778 // I hope width & height are already set.
779 md.video_aspect = (double) md.video_width / md.video_height;
780 }
781 qDebug("MplayerProcess::parseLine: md.video_aspect set to %f", md.video_aspect);
782 }
783 else
784 if (tag == "ID_DVD_DISC_ID") {
785 md.dvd_id = value;
786 qDebug("MplayerProcess::parseLine: md.dvd_id set to '%s'", md.dvd_id.toUtf8().data());
787 }
788 else
789 if (tag == "ID_DEMUXER") {
790 md.demuxer = value;
791 }
792 else
793 if (tag == "ID_VIDEO_FORMAT") {
794 md.video_format = value;
795 }
796 else
797 if (tag == "ID_AUDIO_FORMAT") {
798 md.audio_format = value;
799 }
800 else
801 if (tag == "ID_VIDEO_BITRATE") {
802 md.video_bitrate = value.toInt();
803 }
804 else
805 if (tag == "ID_VIDEO_FPS") {
806 md.video_fps = value;
807 }
808 else
809 if (tag == "ID_AUDIO_BITRATE") {
810 md.audio_bitrate = value.toInt();
811 }
812 else
813 if (tag == "ID_AUDIO_RATE") {
814 md.audio_rate = value.toInt();
815 }
816 else
817 if (tag == "ID_AUDIO_NCH") {
818 md.audio_nch = value.toInt();
819 }
820 else
821 if (tag == "ID_VIDEO_CODEC") {
822 md.video_codec = value;
823 }
824 else
825 if (tag == "ID_AUDIO_CODEC") {
826 md.audio_codec = value;
827 }
828 else
829 if (tag == "ID_CHAPTERS") {
830 md.n_chapters = value.toInt();
831 #ifdef TOO_CHAPTERS_WORKAROUND
832 if (md.n_chapters > 1000) {
833 qDebug("MplayerProcess::parseLine: warning too many chapters: %d", md.n_chapters);
834 qDebug(" chapters will be ignored");
835 md.n_chapters = 0;
836 }
837 #endif
838 }
839 else
840 if (tag == "ID_DVD_CURRENT_TITLE") {
841 dvd_current_title = value.toInt();
842 }
843 else
844 if (tag == "ID_BLURAY_CURRENT_TITLE") {
845 br_current_title = value.toInt();
846 }
847
848 }
849 }
850}
851
852// Called when the process is finished
853void MplayerProcess::processFinished(int exitCode, QProcess::ExitStatus exitStatus) {
854 qDebug("MplayerProcess::processFinished: exitCode: %d, status: %d", exitCode, (int) exitStatus);
855 // Send this signal before the endoffile one, otherwise
856 // the playlist will start to play next file before all
857 // objects are notified that the process has exited.
858 emit processExited();
859 if (received_end_of_file) emit receivedEndOfFile();
860}
861
862void MplayerProcess::gotError(QProcess::ProcessError error) {
863 qDebug("MplayerProcess::gotError: %d", (int) error);
864}
865
866#include "mplayeroptions.cpp"
867#include "moc_mplayerprocess.cpp"
Note: See TracBrowser for help on using the repository browser.