internetradio2.0/streamsourcesrc/irasfplayer.cpp
changeset 0 09774dfdd46b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/internetradio2.0/streamsourcesrc/irasfplayer.cpp	Mon Apr 19 14:01:53 2010 +0300
@@ -0,0 +1,431 @@
+/*
+* Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "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:  Implementation of streaming and playback on ASF channel url
+*
+*/
+
+
+/* ---------------------------------------------------------------------------
+*  Version history:
+*  Template version:
+*  <ccm_history>
+*
+*  Version: 1, Fri Sep 19 13:00:00 2008 by e0328782 Rohit
+*  Ref:
+*  Created
+*
+*  </ccm_history>
+* ============================================================================
+*/
+
+#include <e32property.h>
+#include "irpubsubkeys.h"
+
+#include "irasfplayer.h"				// this class
+#include "irctrlcommand.h"				// MIRCtrlCmdObserver
+#include "irstreamsourceobserver.h"		// MIRStreamSourceObserver
+#include "irdebug.h"
+#include "irmetadata.h"
+
+//Constants
+_LIT8( KMimeTypeASF, "audio/x-ms-wma" );
+const TInt KFour = 4;
+_LIT( KIRSongTitle, "title" );
+_LIT( KIRSongArtist, "artist" );
+_LIT( KTrailingAsf, ".asf" );
+_LIT( KTrailingWma, ".wma" );
+_LIT( KTrailingWmv, ".wmv" );
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// ---------------------------------------------------------------------------
+// CIRAsfPlayer::NewL
+// function returns an instance of CIRAsfPlayer
+// Two phase constructor
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CIRAsfPlayer* CIRAsfPlayer::NewL(MIRStreamSourceObserver& aStreamObserver,
+										  MIRCtrlCmdObserver& aCtrlCmdObserver)
+	{
+	IRLOG_DEBUG( "CIRAsfPlayer::NewL" );
+	CIRAsfPlayer* self = CIRAsfPlayer::NewLC(aStreamObserver, aCtrlCmdObserver );
+	CleanupStack::Pop(self);
+	IRLOG_DEBUG( "CIRAsfPlayer::NewL - Exiting." );
+	return self;
+	}
+
+// ---------------------------------------------------------------------------
+// CIRAsfPlayer::NewLC
+// function creates an instance of CIRAsfPlayer
+// Two phase constructor
+// ---------------------------------------------------------------------------
+//
+CIRAsfPlayer* CIRAsfPlayer::NewLC(MIRStreamSourceObserver& aStreamObserver,
+								  MIRCtrlCmdObserver& aCtrlCmdObserver)
+	{
+	IRLOG_DEBUG( "CIRAsfPlayer::NewLC" );
+	CIRAsfPlayer* self = new (ELeave) CIRAsfPlayer(aStreamObserver, aCtrlCmdObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	IRLOG_DEBUG( "CIRAsfPlayer::NewLC - Exiting." );
+	return self;
+	}
+
+// ---------------------------------------------------------------------------
+// CIRAsfPlayer::~CIRAsfPlayer
+// Default Destructor
+// ---------------------------------------------------------------------------
+//
+CIRAsfPlayer::~CIRAsfPlayer()
+	{
+	IRLOG_DEBUG( "CIRAsfPlayer::~CIRAsfPlayer" );
+    if( iMdaAudioPlayer )
+	    {
+	    delete iMdaAudioPlayer;
+	    iMdaAudioPlayer = NULL;
+	    }
+
+	if( iMetaData )
+		{
+		delete 	iMetaData;
+		iMetaData = NULL;
+		}
+	iStationUri.Close();
+
+	IRLOG_DEBUG( "CIRAsfPlayer::~CIRAsfPlayer - Exiting." );
+	}
+
+//Function for Play control
+
+// ---------------------------------------------------------------------------
+// CIRAsfPlayer::PlayL
+// function to intiate the player and play the stream
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CIRAsfPlayer::PlayL(const TDesC& aUri)
+	{
+	IRRDEBUG2( "CIRAsfPlayer::PlayL - Entering aUri=%S", &aUri );
+
+    iStationUri.Close();
+    iStationUri.CreateL( aUri );
+
+	User::LeaveIfNull( iMdaAudioPlayer );
+    if( iMdaAudioPlayer )
+	    {
+	    iMdaAudioPlayer->Close();
+    	iMdaAudioPlayer->OpenUrlL( iStationUri, KUseDefaultIap, KMimeTypeASF );
+	    }
+
+	IRLOG_DEBUG( "CIRAsfPlayer::PlayL - Exiting." );
+	}
+
+// ---------------------------------------------------------------------------
+// CIRAsfPlayer::Play
+// function to resume playing (AsfPlayer should already initiated using Play(url))
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CIRAsfPlayer::Play()
+	{
+	IRLOG_DEBUG( "CIRAsfPlayer::Play" );
+
+	SetVolume( iCtrlCmdObserver.FetchVolume() );
+    if( iMdaAudioPlayer )
+	    {
+		iMdaAudioPlayer->Play();
+	    }
+
+	IRLOG_DEBUG( "CIRAsfPlayer::Play - Exiting." );
+	}
+
+// ---------------------------------------------------------------------------
+// CIRAsfPlayer::Stop
+// function to which stop the player
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CIRAsfPlayer::Stop()
+	{
+	IRLOG_DEBUG( "CIRAsfPlayer::Stop" );
+
+    if( iMdaAudioPlayer )
+	    {
+		iMdaAudioPlayer->Stop();
+	    }
+
+	IRLOG_DEBUG( "CIRAsfPlayer::Stop - Exiting." );
+	}
+
+										//Functions for Volume Control
+
+// ---------------------------------------------------------------------------
+// CIRAsfPlayer::SetVolume
+// function to set the volume
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CIRAsfPlayer::SetVolume(TInt aVolume )
+	{
+	IRLOG_DEBUG( "CIRAsfPlayer::SetVolume" );
+
+    if( iMdaAudioPlayer )
+	    {
+		iMdaAudioPlayer->SetVolume( aVolume );
+	    }
+
+	IRLOG_DEBUG( "CIRAsfPlayer::SetVolume - Exiting." );
+	}
+
+// ---------------------------------------------------------------------------
+// CIRAsfPlayer::Volume
+// function to returns the volume, integer level of volume is the Output
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CIRAsfPlayer::Volume() const
+	{
+	IRLOG_DEBUG( "CIRAsfPlayer::Volume" );
+
+	TInt volume = 0;
+    if( iMdaAudioPlayer )
+	    {
+		iMdaAudioPlayer->GetVolume( volume );
+	    }
+
+	return volume;
+	}
+
+// ---------------------------------------------------------------------------
+// CIRAsfPlayer::MaxVolume
+// function to returns the maximum volume
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CIRAsfPlayer::MaxVolume() const
+	{
+	IRLOG_DEBUG( "CIRAsfPlayer::MaxVolume" );
+
+	TInt volume = 0;
+    if( iMdaAudioPlayer )
+	    {
+		volume = iMdaAudioPlayer->MaxVolume();
+	    }
+
+	return volume;
+	}
+
+// Helper functions
+
+// ---------------------------------------------------------------------------
+// CIRAsfPlayer::DetectAsfChannel
+// Function is used to detect ASF channel by its url ending in .asf/.wma/.wmv
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TBool CIRAsfPlayer::DetectAsfChannel(const TDesC& aUri)
+	{
+	IRLOG_DEBUG("CIRAsfPlayer::DetectAsfChannel - Entering");
+	TPtrC ptr( aUri );
+	TPtrC UriTypePtr( ptr.Right(KFour) );
+
+	TBool bAsf = UriTypePtr == KTrailingAsf || UriTypePtr == KTrailingWma
+							   || UriTypePtr == KTrailingWmv;
+
+	IRRDEBUG2("CIRAsfPlayer::DetectAsfChannel - ASF Channel detected = %d", (TInt)bAsf);
+	IRLOG_DEBUG("CIRAsfPlayer::DetectAsfChannel - Exiting");
+	return bAsf;
+	}
+
+// Two-phase construction
+
+// ---------------------------------------------------------------------------
+// CIRAsfPlayer::CIRAsfPlayer
+// Default constructor
+// ---------------------------------------------------------------------------
+//
+CIRAsfPlayer::CIRAsfPlayer(MIRStreamSourceObserver& aStreamObserver,
+						   MIRCtrlCmdObserver& aCtrlCmdObserver):
+	iMdaAudioPlayer(NULL), iMetaData(NULL),
+	iCtrlCmdObserver( aCtrlCmdObserver ), iStreamObserver(aStreamObserver),
+	iState( ENotReady )
+	{
+	IRLOG_DEBUG( "CIRAsfPlayer::CIRAsfPlayer" );
+	}
+
+// ---------------------------------------------------------------------------
+// CIRAsfPlayer::ConstructL
+// Two phase constructor is used to intialize data members
+// Function can leave if CMdaAudioOutputStream::NewL leaves
+// ---------------------------------------------------------------------------
+//
+void CIRAsfPlayer::ConstructL()
+	{
+	IRLOG_DEBUG( "CIRAsfPlayer::ConstructL" );
+
+	iMdaAudioPlayer = CMdaAudioPlayerUtility::NewL( *this );
+	User::LeaveIfNull( iMdaAudioPlayer );
+
+	iMdaAudioPlayer->RegisterForAudioLoadingNotification( *this );
+
+	iMetaData = CIRMetaData::NewL();
+	User::LeaveIfNull( iMdaAudioPlayer );
+
+	IRLOG_DEBUG( "CIRAsfPlayer::ConstructL - Exiting." );
+	}
+
+//Call back functions
+
+// ---------------------------------------------------------------------------
+// MMdaAudioPlayerCallback::MapcInitComplete
+// Invoked with OpenUrl() success/fail result
+// ---------------------------------------------------------------------------
+//
+void CIRAsfPlayer::MapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& /*aDuration*/)
+	{
+	IRRDEBUG2( "CIRAsfPlayer::MapcInitComplete - Entering. aError = %d", aError );
+    if( KErrNone == aError )
+	    {
+	    iState = EReadyToPlay;
+	    Play();
+	    iStreamObserver.Asf_ConnectionEstablished();
+    	}
+	else
+		{
+		iState = ENotReady;
+		iStreamObserver.Asf_ErrorConnecting(aError);
+		}
+	IRLOG_DEBUG( "CIRAsfPlayer::MapcInitComplete - Exiting" );
+	}
+
+// ---------------------------------------------------------------------------
+// MMdaAudioPlayerCallback::MapcPlayComplete
+// Invoked after playback of an audio sample completes success/fail
+// ---------------------------------------------------------------------------
+//
+void CIRAsfPlayer::MapcPlayComplete(TInt aError)
+	{
+	IRRDEBUG2( "CIRAsfPlayer::MapcPlayComplete - Entering. aError = %d", aError );
+	if( KErrNone != aError )
+		{
+		iState = ENotReady;
+		iStreamObserver.Asf_ErrorConnecting(aError);
+		}
+	else
+		{
+		// won't hit this as playing from stream
+		}
+	IRLOG_DEBUG( "CIRAsfPlayer::MapcPlayComplete - Exiting" );
+	}
+
+// ---------------------------------------------------------------------------
+// MAudioLoadingObserver::MaloLoadingStarted
+//
+// ---------------------------------------------------------------------------
+//
+void CIRAsfPlayer::MaloLoadingStarted()
+	{
+	IRLOG_DEBUG( "CIRAsfPlayer::MaloLoadingStarted - Entering" );
+	TInt percentComplete = 0;
+
+	if( iMdaAudioPlayer )
+		{
+		iState = EReadyToPlay;
+
+		TRAPD( err, iMdaAudioPlayer->GetAudioLoadingProgressL( percentComplete ));
+		if(err == KErrNone)
+			iStreamObserver.Asf_UpdateProgress( percentComplete );
+		}
+	IRLOG_DEBUG( "CIRAsfPlayer::MaloLoadingStarted - Exiting" );
+	}
+
+// ---------------------------------------------------------------------------
+// MAudioLoadingObserver::MaloLoadingComplete
+//
+// ---------------------------------------------------------------------------
+//
+void CIRAsfPlayer::MaloLoadingComplete()
+	{
+	IRLOG_DEBUG( "CIRAsfPlayer::MaloLoadingComplete - Entering" );
+	TInt percentComplete = 0;
+
+	if( iMdaAudioPlayer )
+		{
+		iState = EPlaying;
+
+		TRAPD( err, iMdaAudioPlayer->GetAudioLoadingProgressL( percentComplete ));
+		if(err == KErrNone)
+			iStreamObserver.Asf_UpdateProgress( percentComplete );
+
+		TRAP( err, ReadMetadataL());
+		if(err != KErrNone)
+			{
+			IRLOG_WARNING( "CIRAsfPlayer::MaloLoadingComplete - Failed to read/publish metadata" );
+			}
+
+		// publish birtate
+		TUint bitrate = 0;
+		err = iMdaAudioPlayer->GetBitRate( bitrate );
+		RProperty::Set( KUidActiveInternetRadioApp, KIRPSBitrate, bitrate );
+		}
+	IRLOG_DEBUG( "CIRAsfPlayer::MaloLoadingComplete - Exiting" );
+	}
+
+// ---------------------------------------------------------------------------
+// CIRAsfPlayer::ReadMetadataL
+// Reads the meta data from the CMdaAudioPlayerUtility
+// ---------------------------------------------------------------------------
+//
+void CIRAsfPlayer::ReadMetadataL()
+	{
+    IRLOG_DEBUG( "CIRAsfPlayer::ReadMetadataL - Entering" );
+
+	if(iMetaData)
+		{
+	    // Erases old meta data information.
+	    iMetaData->SetArtistL( KNullDesC );
+	    iMetaData->SetSongL( KNullDesC );
+	    iMetaData->SetStreamUrlL( KNullDesC );
+
+		// Stream Url
+		iMetaData->SetStreamUrlL( iStationUri );
+
+	    TInt nMetadata = 0;
+	    TInt err = iMdaAudioPlayer->GetNumberOfMetaDataEntries( nMetadata );
+	    for( TInt ctr=0; ctr < nMetadata; ++ctr )
+	        {
+	        CMMFMetaDataEntry* pMetadataEntry = iMdaAudioPlayer->GetMetaDataEntryL( ctr );
+
+	        // Song Title
+	        if( pMetadataEntry->Name() == KIRSongTitle )
+	        	{
+	        	iMetaData->SetSongL( pMetadataEntry->Value() );
+	        	}
+	        // Song Artist
+	        else if( pMetadataEntry->Name() == KIRSongArtist )
+	        	{
+	        	iMetaData->SetArtistL( pMetadataEntry->Value() );
+	        	}
+	        }
+
+		if( iMetaData->Song().Length() == 0 )
+			{
+			IRLOG_WARNING( "CIRAsfPlayer::ExtractMetaDataL - song \"title\" not found in metadata" );
+			}
+		if( iMetaData->Artist().Length() == 0 )
+			{
+			IRLOG_WARNING( "CIRAsfPlayer::ExtractMetaDataL - song \"artist\" not found in metadata" );
+			}
+
+		// Notify observer
+		iStreamObserver.Asf_HandleMetaDataReceivedL( *iMetaData );
+
+	    IRLOG_DEBUG4( "CIRAsfPlayer::ReadMetadataL - Exiting (artist=%S, song=%S, streamUrl=%S)",
+	    		     &iMetaData->Artist(), &iMetaData->Song(), &iMetaData->StreamUrl() );
+		}
+	}