📄 mediaplayer.cpp
字号:
/************************************************************************ Copyright (C) 2000-2005 Trolltech AS. All rights reserved.**** This file is part of the Qtopia Environment.** ** This program is free software; you can redistribute it and/or modify it** under the terms of the GNU General Public License as published by the** Free Software Foundation; either version 2 of the License, or (at your** option) any later version.** ** A copy of the GNU GPL license version 2 is included in this package as ** LICENSE.GPL.**** This program is distributed in the hope that it will be useful, but** WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ** See the GNU General Public License for more details.**** In addition, as a special exception Trolltech gives permission to link** the code of this program with Qtopia applications copyrighted, developed** and distributed by Trolltech under the terms of the Qtopia Personal Use** License Agreement. You must comply with the GNU General Public License** in all respects for all of the code used other than the applications** licensed under the Qtopia Personal Use License Agreement. If you modify** this file, you may extend this exception to your version of the file,** but you are not obligated to do so. If you do not wish to do so, delete** this exception statement from your version.** ** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#define QTOPIA_INTERNAL_LOADTRANSLATIONS#include <qtopia/qpeapplication.h>#include <qtopia/qcopenvelope_qws.h>#include <qtopia/applnk.h>#include <qtopia/resource.h>#include <qmessagebox.h>#include <qpainter.h>#include <qtimer.h>#include <qfile.h>#ifndef QT_NO_TRANSLATION#include <stdlib.h>#endif#include "audiodevice.h"#include "controlwidgetbase.h"#include "loopcontrolbase.h"#include "mediaselectorwidget.h"#include "mediaplayer.h"/*! \class MediaPlayer mediaplayer.h \brief This class is specific to the mediaplayer apps. It is currently private to those apps, and its API, and therefore binary compatibilty may change in later versions. This class creates all the elements of playing media files and ties them together. It abstracts what GUI elements are used with a few virtual functions: createMediaSelector(), createAudioUI() and createVideoUI(). This should make it possible to make some different frontends with the backend mostly the same abstracted behind an API like this. This API is subject to change.*/MediaPlayerState *mediaPlayerState = 0;MediaPlayer::MediaPlayer( QWidget *parent, const char *name, WFlags ) : QWidgetStack( parent, name ), scanSpeed( 0 ), upTimerId( 0 ), dnTimerId( 0 ), rtTimerId( 0 ), ltTimerId( 0 ), aw( 0 ), vw( 0 ), loopControlBase( 0 ), ad( 0 ), list( 0 ), docLnk( 0 ), disabledSuspendScreenSaver(false), previousSuspendMode(false){#ifndef QT_NO_TRANSLATION QPEApplication::loadTranslations(QString("libmediaplayer"));#endif setMinimumSize( 128, 128 ); QObject::connect( qApp, SIGNAL( appMessage(const QCString&,const QByteArray&) ), this, SLOT( appMessage(const QCString&,const QByteArray&) ) ); QTimer::singleShot( 0, this, SLOT( createMediaPlayer() ) ); qApp->installEventFilter( this );}MediaPlayer::~MediaPlayer(){ delete docLnk; delete list; delete loopControlBase; delete mediaPlayerState; delete aw; delete vw;}void MediaPlayer::createMediaPlayer(){ QPainter p( this ); QPixmap waitPix = Resource::loadPixmap( "bigwait" ); p.drawPixmap( (width() - waitPix.width()) / 2, (height() - waitPix.height()) / 2, waitPix ); mediaPlayerState = new MediaPlayerState( 0, "mediaPlayerState" ); connect( mediaPlayerState, SIGNAL( viewChanged(View) ), this, SLOT( setView(View) ) ); list = createMediaSelector(); if ( list ) { addWidget( list->widget(), 0 ); if ( docString.isEmpty() && url.isEmpty() ) { raiseWidget( list->widget() ); // If started normally, show playlist first list->widget()->show(); // show qApp->processEvents(); // (shows up now) // Start loading up the UIs up in the background if they haven't been already QTimer::singleShot( 1000, this, SLOT( audioUI() ) ); QTimer::singleShot( 2000, this, SLOT( videoUI() ) ); } } mediaPlayerState->loadPlugins(); // Load plugins and create loopControlBasecontrol and mediaplayer classes connect( mediaPlayerState, SIGNAL( playingToggled(bool) ), this, SLOT( setPlaying(bool) ) ); connect( mediaPlayerState, SIGNAL( pausedToggled(bool) ), this, SLOT( pauseCheck(bool) ) ); connect( mediaPlayerState, SIGNAL( increaseVolume() ), this, SLOT( startIncreasingVolume() ) ); connect( mediaPlayerState, SIGNAL( endIncreaseVolume() ), this, SLOT( stopIncreasingVolume() ) ); connect( mediaPlayerState, SIGNAL( decreaseVolume() ), this, SLOT( startDecreasingVolume() ) ); connect( mediaPlayerState, SIGNAL( endDecreaseVolume() ), this, SLOT( stopDecreasingVolume() ) ); connect( mediaPlayerState, SIGNAL( scanForward() ), this, SLOT( startScanningForward() ) ); connect( mediaPlayerState, SIGNAL( endScanForward() ), this, SLOT( stopScanningForward() ) ); connect( mediaPlayerState, SIGNAL( scanBackward() ), this, SLOT( startScanningBackward() ) ); connect( mediaPlayerState, SIGNAL( endScanBackward() ), this, SLOT( stopScanningBackward() ) ); loopControlBase = createLoopControl(); if ( !docString.isEmpty() ) setDocument( docString ); else if ( !url.isEmpty() ) playURL( url, mimetype ); else if ( docLnk ) playDocLnk( docLnk ); if ( list ) list->loadFiles(); // Load files after getting the main window up and handling setDocuments}ControlWidgetBase *MediaPlayer::audioUI(){ if ( !aw ) { aw = createAudioUI(); if ( aw ) addWidget( aw, 1 ); } return aw;}ControlWidgetBase *MediaPlayer::videoUI(){ if ( !vw ) { vw = createVideoUI(); if ( vw ) addWidget( vw, 2 ); } return vw;}AudioDevice *MediaPlayer::audioDevice(){ if ( !ad ) ad = createAudioDevice(); return ad;}void MediaPlayer::setDocument( const QString& fileref ){ if ( loopControlBase ) { if ( fileref.isNull() ) error(tr("Invalid File"), tr("<qt>There was a problem in getting the file.</qt>")); else { if ( list ) list->setDocument(fileref); // Start playing mediaPlayerState->setPlaying(false); QTimer::singleShot( 1, mediaPlayerState, SLOT( setPlaying() ) ); } } else { docString = fileref; }}void MediaPlayer::closeEvent( QCloseEvent *ce ){ if ( !visibleWidget() || visibleWidget()->close() ) QWidgetStack::closeEvent( ce );}void MediaPlayer::appMessage( const QCString &msg, const QByteArray &data ){ if ( msg == "openURL(QString,QString)" ) { QDataStream stream( data, IO_ReadOnly ); stream >> url >> mimetype; QPEApplication::setKeepRunning(); playURL( url, mimetype ); }}void MediaPlayer::setView( View view ){ switch ( view ) { case AudioView: if ( audioUI() ) raiseWidget( audioUI() ); break; case VideoView: if ( videoUI() ) raiseWidget( videoUI() ); break; case ListView: if ( list ) raiseWidget( list->widget() ); break; default: break; }}bool MediaPlayer::eventFilter( QObject *o, QEvent *e ){ if ( e->type() == QEvent::WindowActivate && o == this && mediaPlayerState ) { if ( mediaPlayerState->view() == VideoView && videoUI() ) videoUI()->makeVisible(); if ( mediaPlayerState->view() == AudioView && audioUI() ) audioUI()->makeVisible(); } return QObject::eventFilter( o, e );}void MediaPlayer::pauseCheck( bool b ){ // Only pause if playing if ( b && !mediaPlayerState->playing() ) mediaPlayerState->setPaused( false );}void MediaPlayer::error(const QString& error, const QString& errorMsg){ QMessageBox::critical( 0, error, errorMsg ); mediaPlayerState->setPlaying(false); mediaPlayerState->closeView();}void MediaPlayer::setTickerText(QString file){ QString tickerText = " " + file + " "; long seconds = loopControlBase->totalPlaytime() / 1000; if ( seconds > 0 ) tickerText += tr( "Length: %1" ).arg( ControlWidgetBase::toTimeString( seconds ) ) + " "; if ( audioUI() ) audioUI()->setTickerText( tickerText ); if ( videoUI() ) videoUI()->setTickerText( tickerText );}void MediaPlayer::setPlaying(bool play){ if ( play ) { if ( mediaPlayerState->paused() ) { // resume from pause mediaPlayerState->setPaused(false); } else { if ( list ) playDocLnk(list->current()); else playDocLnk(docLnk); } } else { stop(false); mediaPlayerState->setPaused(false); }}void MediaPlayer::startDecreasingVolume(){ if ( dnTimerId ) return; dnTimerId = startTimer( 100 ); audioDevice()->decreaseVolume();}void MediaPlayer::startIncreasingVolume(){ if ( upTimerId ) return; upTimerId = startTimer( 100 ); audioDevice()->increaseVolume();}void MediaPlayer::startScanningBackward(){ scanning = FALSE; if ( ltTimerId ) return; scanSpeed = 64; mediaPlayerState->setSeeking( true ); ltTimerId = startTimer( 100 );}void MediaPlayer::startScanningForward(){ scanning = FALSE; if ( rtTimerId ) return; scanSpeed = 64; mediaPlayerState->setSeeking( true ); rtTimerId = startTimer( 100 );}void MediaPlayer::stopDecreasingVolume(){ if ( dnTimerId ) { killTimer( dnTimerId ); dnTimerId = 0; }}void MediaPlayer::stopIncreasingVolume(){ if ( upTimerId ) { killTimer( upTimerId ); upTimerId = 0; }}void MediaPlayer::stopScanningBackward(){ if ( ltTimerId ) { killTimer( ltTimerId ); ltTimerId = 0; if ( rtTimerId ) return; mediaPlayerState->setSeeking( false ); if ( !scanning ) mediaPlayerState->setPrev(); }}void MediaPlayer::stopScanningForward(){ if ( rtTimerId ) { killTimer( rtTimerId ); rtTimerId = 0; if ( ltTimerId ) return; mediaPlayerState->setSeeking( false ); if ( !scanning ) mediaPlayerState->setNext(); }}void MediaPlayer::timerEvent( QTimerEvent *te ){ scanSpeed = (scanSpeed < 8) ? 8 : scanSpeed; if ( te->timerId() == dnTimerId ) { audioDevice()->decreaseVolume(); if ( audioUI() ) audioUI()->updateVolume(); if ( videoUI() ) videoUI()->updateVolume(); } else if ( te->timerId() == upTimerId ) { audioDevice()->increaseVolume(); if ( audioUI() ) audioUI()->updateVolume(); if ( videoUI() ) videoUI()->updateVolume(); } else if ( te->timerId() == ltTimerId ) { internalScan(Left); } else if ( te->timerId() == rtTimerId ) { internalScan(Right); }}void MediaPlayer::internalScan(ScanDirection scanDirection){ scanning = TRUE; if ( mediaPlayerState->seekable() ) { int length = mediaPlayerState->length(); int increment = length / scanSpeed; scanSpeed = scanSpeed * 7 / 8; int newPos = mediaPlayerState->position() + ((scanDirection == Right) ? increment : -increment); if ( newPos > 0 && newPos <= length ) mediaPlayerState->setPosition( newPos ); else if ( newPos > length ) mediaPlayerState->setPosition( length ); else mediaPlayerState->setPosition( 0 ); }}void MediaPlayer::play(){ bool hasVideo = loopControlBase->hasVideo(); if ( !disabledSuspendScreenSaver || previousSuspendMode != hasVideo ) { disabledSuspendScreenSaver = TRUE; previousSuspendMode = hasVideo; // Stop the screen from blanking and power saving state QPEApplication::setTempScreenSaverMode(hasVideo ? QPEApplication::Disable : QPEApplication::DisableSuspend); } mediaPlayerState->setView( hasVideo ? VideoView : AudioView ); loopControlBase->start(); mediaPlayerState->setPlaying( true );}void MediaPlayer::stop(bool willPlayAgainShortly){ if ( !willPlayAgainShortly && disabledSuspendScreenSaver ) { disabledSuspendScreenSaver = FALSE; // Re-enable the suspend mode QPEApplication::setTempScreenSaverMode(QPEApplication::Enable); } loopControlBase->stop();}void MediaPlayer::playDocLnk(const DocLnk *lnk){ if ( !loopControlBase ) return; if ( !lnk ) { return; } delete docLnk; docLnk = new DocLnk(*lnk); qDebug("playDocLnk %s %s", docLnk->file().latin1(), docLnk->name().latin1()); playFile(docLnk->file(), docLnk->name());}void MediaPlayer::playFile(const QString &fileStr, const QString &nameStr){ stop(true); mediaPlayerState->setPaused(false); if ( !QFile::exists( fileStr ) ) { error( tr( "File not found" ), tr( "<qt>The following file was not found: <br>%1<br><i>%2</i></qt>" ).arg( nameStr ).arg( fileStr ) ); return; } if ( !mediaPlayerState->decoder( fileStr ) ) { error( tr( "No decoder found" ), tr( "<qt>Sorry, no appropriate decoders found for this file: <br>%1<br><i>%2</i></qt>" ).arg( nameStr ).arg( fileStr ) ); return; } if ( !loopControlBase->init(fileStr) ) { error( tr( "Error opening file" ), tr( "<qt>Sorry, an error occurred trying to play the file: <br>%1<br><i>%2</i></qt>" ).arg( nameStr ).arg( fileStr ) ); return; } play(); setTickerText(tr("File: %1").arg(nameStr));}void MediaPlayer::playURL(const QString &URL, const QString &mime){ url = URL; mimetype = mime; if ( !loopControlBase ) return; stop(true); mediaPlayerState->setPaused(false); if ( !mediaPlayerState->streamingDecoder(URL, mimetype) ) { error( tr("No decoder found"), tr("<qt>Sorry, no appropriate decoders found for the url: <i>%1</i></qt>").arg(URL) ); return; } if ( !loopControlBase->init(URL, mimetype, true) ) { error( tr("Error opening file"), tr("<qt>Sorry, an error occurred trying to play the url: <i>%1</i></qt>").arg(URL) ); return; } play(); setTickerText(tr("URL: %1").arg(URL));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -