diff -r 000000000000 -r 84ad3b177aa3 browserplugins/browseraudiovideoplugin/src/BavpControllerAudio.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/browserplugins/browseraudiovideoplugin/src/BavpControllerAudio.cpp Mon Mar 30 12:49:49 2009 +0300 @@ -0,0 +1,479 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Controller class for handling browser requests to play video +* +*/ + + +// INCLUDE FILES +#include // For priority/pref values +#include + +#include "BavpLogger.h" +#include "BavpControllerAudio.h" +#include "BavpView.h" + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CBavpControllerAudio::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +CBavpControllerAudio* CBavpControllerAudio::NewL( MBavpView* aView, + TUint aAccessPtId, + TBavpMediaType aMediaType, + const TDesC& aFileName ) + { + CBavpControllerAudio* self = new( ELeave ) CBavpControllerAudio( aView, aAccessPtId ); + + Log( EFalse, _L("CBavpControllerAudio::NewL this="), (TInt)self ); + + CleanupStack::PushL( self ); + self->ConstructL( aMediaType, aFileName ); + CleanupStack::Pop( self ); + return self; + } + +// ----------------------------------------------------------------------------- +// CBavpControllerAudio::~CBavpControllerAudio() +// Destructor +// ----------------------------------------------------------------------------- +CBavpControllerAudio::~CBavpControllerAudio() + { + Log( EFalse, _L("CBavpControllerAudio::~CBavpControllerAudio") ); + + // If currently playing, call Stop before you close and delete + if ( iCurrentState == EBavpPlaying && iAudioPlayer != NULL) + { + iAudioPlayer->Stop(); + } + if ( iAudioPlayer ) + { + iAudioPlayer->Close(); + delete iAudioPlayer; + } + + iFs.Close(); + } + +// ----------------------------------------------------------------------------- +// CBavpControllerAudio::CBavpControllerAudio +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +CBavpControllerAudio::CBavpControllerAudio( MBavpView* aView, + TUint aAccessPtId ) + : CBavpController( aView, aAccessPtId ) + { + } + +// ----------------------------------------------------------------------------- +// CBavpControllerAudio::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +void CBavpControllerAudio::ConstructL( TBavpMediaType aMediaType, + const TDesC& aFileName ) + { + // Construct the BavpController base class + BaseConstructL( aMediaType, aFileName ); + + // Create Audio Player Client: + iAudioPlayer = CMdaAudioPlayerUtility::NewL( *this, KAudioPriorityRealOnePlayer, + TMdaPriorityPreference( KAudioPrefRealOneLocalPlayback ) ); + + // Connect to file server: + User::LeaveIfError( iFs.Connect() ); + } + +// ----------------------------------------------------------------------------- +// CBavpControllerAudio::OpenAudioUrlL +// Open the audio url link +// ----------------------------------------------------------------------------- +void CBavpControllerAudio::OpenAudioUrlL() + { + Log( EFalse, _L("CBavpControllerAudio::OpenUrlL() ") ); + + // Note: Play() is called from MapcInitComplete() + iAudioPlayer->OpenUrlL( *iClipInfo->iUrl, iAccessPtId, KNullDesC8 ); + } + +// ----------------------------------------------------------------------------- +// CBavpControllerAudio::OpenAudioFileL +// Open the audio file +// ----------------------------------------------------------------------------- +void CBavpControllerAudio::OpenAudioFileL() + { + Log( EFalse, _L("CBavpControllerAudio::OpenFileL() ") ); + + // Note: Play() is called from MapcInitComplete() + iAudioPlayer->OpenFileL( *iClipInfo->iFileName ); + } + +// ----------------------------------------------------------------------------- +// CBavpControllerAudio::PlayAudioVideoL +// Handles request to open and play an audio or video file +// TDesC& aFilename: Name of audio file, or video file, or URL link +// ----------------------------------------------------------------------------- +void CBavpControllerAudio::PlayAudioVideoL() + { + Log( EFalse, _L("CBavpControllerAudio::OpenAndPlayL() ") ); + + // If currently playing, call Stop before you attempt to open and play + if ( iCurrentState == EBavpPlaying ) + { + Stop(); + } + + OpenAudioFileL(); + } + +// ----------------------------------------------------------------------------- +// CBavpControllerAudio::Stop +// Stops audio from playing, if playing. +// ----------------------------------------------------------------------------- +void CBavpControllerAudio::Stop() + { + Log( EFalse, _L("CBavpControllerAudio::Stop") ); + + iAudioPlayer->Stop(); + iClipInfo->iPosition = 0; + iAudioPlayer->SetPosition( iClipInfo->iPosition ); + iCurrentState = EBavpStopped; + + iBavpView->UpdateView(); + } + +// ----------------------------------------------------------------------------- +// CBavpControllerAudio::Play +// Non leaving method to play audio +// ----------------------------------------------------------------------------- +void CBavpControllerAudio::Play() + { + // To keep LeaveScan from complaining everwhere, we use this non leaving + // method + TRAP_IGNORE( PlayL() ); + } + +// ----------------------------------------------------------------------------- +// CBavpControllerAudio::PlayL +// Plays audio +// ----------------------------------------------------------------------------- +void CBavpControllerAudio::PlayL() + { + Log( EFalse, _L("CBavpControllerAudio::PlayL") ); + + SetPlayerVolume( iCurrentVolume ); + + // Handle multiple media object case + if ( iBavpControllerArray.Count() > 1 && IsAnotherControllerPlaying() ) + { + if ( iLastCommand == EBavpCmdPlay ) + { + // Another controller is playing, and the user wants to play + // this media object. Pause (or stop) all of the others and + // play this one. + PauseOtherControllersPlaying(); + } + } + + iAudioPlayer->SetPosition( iClipInfo->iPosition ); + iAudioPlayer->Play(); + iCurrentState = EBavpPlaying; + + iBavpView->UpdateView(); + } + +// ----------------------------------------------------------------------------- +// CBavpControllerAudio::Pause +// Non leaving method to pause playing audio +// ----------------------------------------------------------------------------- +void CBavpControllerAudio::Pause() + { + // To keep LeaveScan from complaining everwhere, we use this non leaving + // method + TRAP_IGNORE( PauseL() ); + } + +// ----------------------------------------------------------------------------- +// CBavpControllerAudio::PauseL +// Pauses video while playing, if playing. +// ----------------------------------------------------------------------------- +void CBavpControllerAudio::PauseL() + { + Log( EFalse, _L("CBavpControllerAudio::PauseL") ); + + if ( IsClipSeekable() && + (iCurrentState == EBavpPlaying || iCurrentState == EBavpPaused)) + { + // Save clip position, in case we want to resume playing + iAudioPlayer->GetPosition(iClipInfo->iPosition); + iAudioPlayer->Pause(); + iCurrentState = EBavpPaused; + } + else + { + // Not seekable content, i.e. Live stream + iAudioPlayer->Stop(); + iClipInfo->iPosition = 0; + iCurrentState = EBavpStopped; + } + + iBavpView->UpdateView(); + } + +// ----------------------------------------------------------------------------- +// CBavpControllerAudio::FastForwardL +// Fast forwards the audio +// ----------------------------------------------------------------------------- +void CBavpControllerAudio::FastForwardL() + { + } + +// ----------------------------------------------------------------------------- +// CBavpControllerAudio::RewindL +// Rewinds the audio +// ----------------------------------------------------------------------------- +void CBavpControllerAudio::RewindL() + { + } + +// ----------------------------------------------------------------------------- +// CBavpControllerAudio::SetPlayerVolume +// Calculate the player volume from the CR volume (aka BavpController +// volume value) and sets it +// ----------------------------------------------------------------------------- +void CBavpControllerAudio::SetPlayerVolume( TInt aVolume ) + { + TInt playerVolume( 0 ); + if ( iPlayerInitialized ) + { + TInt maxVolume = iAudioPlayer->MaxVolume(); + if (aVolume < 0) + { + playerVolume = 0; + } + else if (aVolume > maxVolume) + { + playerVolume = maxVolume; + } + else + { + // The CR volume is 0-10, convert to Audio player volume 0-100 + playerVolume = ( aVolume * iPlayerMaxVolume ) / KCRVolumeMax; + } + + // Set Video player volume + iAudioPlayer->SetVolume( playerVolume ); + } + } + +// ----------------------------------------------------------------------------- +// CBavpControllerAudio::GetPlayerVolume +// Calculate the player volume value and sets the playback volume for the audio +// track of the video clip. +// ----------------------------------------------------------------------------- +TInt CBavpControllerAudio::GetPlayerVolume() + { + TInt playerVolume( 0 ); + TInt CRVolume( 0 ); + + if ( iPlayerInitialized ) + { + // Audio player returns 0-100 + iAudioPlayer->GetVolume( playerVolume ); + + // Convert to CR volume 0-10 + CRVolume = ( playerVolume * KCRVolumeMax ) / iPlayerMaxVolume; + } + + return CRVolume; + } + +// -------------------------------------------------------------------------- +// CBavpControllerAudio::HandleError +// Handle error codes. We can receive errors from the MMF Video Player +// and its MMF callbacks (mvpuoPlayComplete, etc). +// The MMF errors are for handling content issues, such as decoding content +// and network access. +// NOTES: +// MMF errors start at -12000, see /epoc32/include/mmf/common/MMFErrors.h +// MMF also returns -1 (KErrNotFound) and few other system-wide errors +// ----------------------------------------------------------------------------- +void CBavpControllerAudio::HandleError( TInt aError ) + { + Log( EFalse, _L("In CBavpControllerAudioo::HandleError(): err="), aError ); + + switch ( aError ) + { + case KErrMMVideoDevice: + case KErrMMAudioDevice: + // We get this when the controllers can only support + // playing one media at a time. + HandleMultiInstanceError(); + break; + + default: + iCurrentState = EBavpBadContent; + iBavpView->UpdateView(); + break; + } + } + +// ----------------------------------------------------------------------------- +// CBavpControllerAudio::MapcInitComplete +// Required due to MMdaAudioPlayerCallback derivation. +// Called by client to indicate initialization has completed and device is ready +// to play. +// ----------------------------------------------------------------------------- +void CBavpControllerAudio::MapcInitComplete( TInt aError, + const TTimeIntervalMicroSeconds& /*aDuration */ ) + { + Log( EFalse, _L("MapcInitComplete aError="), aError ); + + // Check for error + if ( aError != KErrNone ) + { + HandleError( aError ); + return; + } + + // Audio player is initialized, so we can interact with it, volume, + iPlayerInitialized = ETrue; + + iClipInfo->iDurationInSeconds = iAudioPlayer->Duration(); + iClipInfo->iPosition = 0; + iAudioPlayer->SetPosition( iClipInfo->iPosition ); + + // Get the max player volume, so we can scale volume + iClipInfo->iMaxVolume = iAudioPlayer->MaxVolume(); + iPlayerMaxVolume = iClipInfo->iMaxVolume; + + // Handle multiple media object case + if ( iBavpControllerArray.Count() > 1 && IsAnotherControllerPlaying() ) + { + if ( iLastCommand == EBavpCmdUnknown ) + { + // Another controller is playing, and this controller was + // initializing. Because we can only play one media object at a + // time, stop this media and let the first one + // initialized continue to play. + Stop(); + } + else if ( iCurrentState == EBavpPlaying && iLastCommand == EBavpCmdPlay ) + { + // Another controller is playing, and the user wants to play + // another media object. Pause (or stop) all of the others and + // play this one. + PauseOtherControllersPlaying(); + Play(); + } + } + // Handle the single media object case + else + { + Play(); + } + + // Stop the buffering animation and play the audio only animation + iBavpView->UpdateView(); + } + +// ----------------------------------------------------------------------------- +// CBavpControllerAudio::MapcPlayComplete +// Required due to MMdaAudioPlayerCallback derivation. +// Called by client to indicate audio file has completed or has stopped playing. +// ----------------------------------------------------------------------------- +void CBavpControllerAudio::MapcPlayComplete( TInt aError ) + { + Log( EFalse, _L("MapcPlayComplete aError="), aError ); + + if ( iInfiniteLoopFlag ) + { + // If infinite flag set: play audio again and again... + iClipInfo->iPosition = 0; + Play(); + } + else if ( ( iLoopCount - 1 ) > 0 ) + { + // If loop count: play, decrement loop count, play again... + iClipInfo->iPosition = 0; + Play(); + iLoopCount-- ; + } + else + { + // We're done looping, or just done playing the audio + iCurrentState = EBavpPlayComplete; + iClipInfo->iPosition = 0; + iLoopCount = iInitLoopCount; + + iBavpView->UpdateView(); + } + } + +// ----------------------------------------------------------------------------- +// CBavpControllerAudio::getPositionL +// To get the current position of the clip +// ----------------------------------------------------------------------------- + + TTimeIntervalMicroSeconds CBavpControllerAudio::getPositionL() + { + if ( iAudioPlayer ) + { + TTimeIntervalMicroSeconds pos; + iAudioPlayer->GetPosition( pos ); + return pos; + } + return NULL; + } + + // ----------------------------------------------------------------------------- +// CBavpControllerAudio::setPositionL +// To set the position of the clip +// ----------------------------------------------------------------------------- + + void CBavpControllerAudio::setPositionL( TTimeIntervalMicroSeconds val ) + { + if ( iAudioPlayer ) + { + + if ( !IsClipSeekable() && !IsClipLocalMedia() ) + { + return; + } + + TBool didWePause = EFalse; + // If playing, pause it (PauseL stops the PositionUpdater) + if ( iCurrentState == EBavpPlaying ) + { + PauseL(); + didWePause = ETrue; + } + + if ( (val > iClipInfo->iDurationInSeconds ) || (val < 0) ) + { + val = 0; + } + + iAudioPlayer->SetPosition(val); + iClipInfo->iPosition = val; + if ( didWePause ) + { + PlayL(); + } + } + } + + +// End of File