⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shoutcastadapter.cpp

📁 这是一个使用 ShortCast的IP网络流式播放的symbian的软件源码.里面有ShortCast短播协议的实现以及AAC音频,MP3音频流式播放的实现.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
* ==============================================================================
*  Name        : ShoutcastAdapter.cpp
*  Part of     : Shoutcast Engine
*  Description : This class implements the shoutcast adapter interface.
*  Version     : 1
*
*  Copyright (c) 2006, Nokia Corporation All rights reserved. Redistribution
*  and use in source and binary forms, with or without modification, are
*  permitted provided that the following conditions are met: Redistributions
*  of source code must retain the above copyright notice, this list of
*  conditions and the following disclaimer. Redistributions in binary form
*  must reproduce the above copyright notice, this list of conditions and the
*  following disclaimer in the documentation and/or other materials provided
*  with the distribution. Neither the name of the Nokia Corporation nor the
*  names of its contributors may be used to endorse or promote products
*  derived from this software without specific prior written permission. THIS
*  SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
*  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
*  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
*  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
*  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
*  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
*  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
*  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
*  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
*  POSSIBILITY OF SUCH DAMAGE.
* ==============================================================================
*/

// INCLUDE FILES
#include <eikmenup.h>
#include <eikapp.h>
#include <AknGlobalNote.h>
#include <ImplementationProxy.h>
#include <S60InternetRadio.rsg>
#include "MInternetRadioAdapterObserver.h"
#include "S60InternetRadio.hrh"
#include "ShoutcastDefs.h"
#include "ShoutcastErrors.h"
#include "ShoutcastUIDs.hrh"
#include "ShoutcastAdapter.h"
#include "ShoutcastStream.h"
#include "scmetadata.h"

// Identifying string for this audio utility
_LIT(KShoutcastAdapter, "Internet Radio");

const TInt KDefaultVolumeLevel = 2;
const TInt KMaxFileSize = 65535;
const TInt KLineFeed = 0x0A;
const TInt KCarriageReturn = 0x0D;


// ============================ MEMBER FUNCTIONS ===============================

// -----------------------------------------------------------------------------
// CShoutcastAdapter::CShoutcastAdapter
// C++ default constructor can NOT contain any code, that might leave.
// -----------------------------------------------------------------------------
//
CShoutcastAdapter::CShoutcastAdapter(
	MInternetRadioAdapterObserver *aObserver )
	: CPluginAdapter(aObserver)
    {
	iState = ENotReady;
	iPrimed = EFalse;
    }

// -----------------------------------------------------------------------------
// CShoutcastAdapter::NewL
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CShoutcastAdapter* CShoutcastAdapter::NewL(
	MInternetRadioAdapterObserver *aObserver )
    {
    CShoutcastAdapter* self = new (ELeave) CShoutcastAdapter(aObserver);
    CleanupStack::PushL(self);
    self->ConstructL();
	CleanupStack::Pop(self);
    return self;
    }

// -----------------------------------------------------------------------------
// CShoutcastAdapter::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CShoutcastAdapter::ConstructL()
	{
	LOG_START;
	//TParse parse;

	_LIT(dir, "\\Shoutcast\\");
	_LIT(wildName,"*.pls");

    FindPlayListsL(dir, wildName);
	}


// -----------------------------------------------------------------------------
// CShoutcastAdapter::FindPlayLists
// Open the requested URL and create the stream
// -----------------------------------------------------------------------------
//
void CShoutcastAdapter::FindPlayListsL(
	const TDesC& aDir,
	const TDesC& aWildname )
	{
	RFs fs;
	//RFile file;
	TBuf<50> text;

	User::LeaveIfError(fs.Connect());
	CleanupClosePushL(fs);

	text.Copy(_L("Building Playlist"));
	iWaitingNote = CAknGlobalNote::NewL();
	iWaitingNoteId = iWaitingNote->ShowNoteL(EAknGlobalWaitNote,text);

	TFindFile file_finder(fs);
    CDir* file_list;
    TInt err = file_finder.FindWildByDir(aWildname, aDir, file_list);

    while ( err == KErrNone )
        {
        TInt i;
        for (i=0; i<file_list->Count(); i++)
            {
            TParse fullentry;
            fullentry.Set((*file_list)[i].iName,& file_finder.File(),NULL);
            // It's ok if the parse fail leave on this file, we'll try to parse the next one.
            TRAPD(r,ParsePlaylistFileL(fs, fullentry.FullName()));
            }
        delete file_list;
        err=file_finder.FindWild(file_list);
        }

	CleanupStack::Pop();
	fs.Close();

	iWaitingNote->CancelNoteL(iWaitingNoteId);
	iWaitingNoteId=0;
	delete iWaitingNote;
	iWaitingNote=NULL;

	CAknGlobalNote *note = CAknGlobalNote::NewLC();
	text.Copy(_L("Select a station to listen."));
	note->ShowNoteL(EAknGlobalInformationNote ,text);
	CleanupStack::PopAndDestroy(note);

	}



// -----------------------------------------------------------------------------
// CShoutcastAdapter::OpenUrlL
// Open the requested URL and create the stream
// -----------------------------------------------------------------------------
//
void CShoutcastAdapter::OpenUrlL(
	TInt aUrl )
	{
	LOG("OpenUrlL");

	iStreamSource = CShoutcastStream::NewL(*iURLs[aUrl], *this);
	iStreamSource->SetVolume(KDefaultVolumeLevel);
	iNrMetadata = iStreamSource->GetNumberOfMetaDataEntries();

	iState=EReadyToPlay;
	iPrimed=EFalse;
	iObserver->ResetMetadata();

	LOG("OpenUrlL OK");
	}

// -----------------------------------------------------------------------------
// CShoutcastAdapter::CloseUrl
// Closes the currently opened URL and delete the stream
// -----------------------------------------------------------------------------
//
void CShoutcastAdapter::CloseUrl()
	{
	LOG("CloseUrl");
	delete iStreamSource;
	iStreamSource = NULL;
	iState = ENotReady;
	LOG("CloseUrl OK");
	}

// -----------------------------------------------------------------------------
// CShoutcastAdapter::~CShoutcastAdapter
// -----------------------------------------------------------------------------
//
CShoutcastAdapter::~CShoutcastAdapter()
	{
	LOG("Destructor");
	CloseUrl();
	delete iWaitingNote;
	iWaitingNote = NULL;
	delete iErrorNote;
	iErrorNote = NULL;
	delete iWaitDialog;
	iWaitDialog = NULL;
    iURLs.ResetAndDestroy();
	LOG("Destructor OK");
	LOG_END;
	}

// -----------------------------------------------------------------------------
// CShoutcastAdapter::GetMenuText
// -----------------------------------------------------------------------------
//
void CShoutcastAdapter::GetMenuText(
	TDes &aName )
	{
	LOG("GetMenuText")
	aName.Copy(KShoutcastAdapter);
	LOG("GetMenuText OK")
	}

// -----------------------------------------------------------------------------
// CShoutcastAdapter::GetMenuCommand
// This menu command number is used on the UI level. When the user selects a
// utility on the menu, this command number is used to find this adapter.
// The usage is like the hard-coded command values in the menu resource (rss).
// -----------------------------------------------------------------------------
//
TInt CShoutcastAdapter::GetMenuCommand()
	{
	return 0x2001; //Should be a defined constant
	}

// -----------------------------------------------------------------------------
// CShoutcastAdapter::AddExtraMenu
// Add each item in the playlist as an entry to the "Stations" menu.
// -----------------------------------------------------------------------------
//
void CShoutcastAdapter::AddExtraMenu(
	CEikMenuPane* aMenuPane )
	{
	LOG("AddExtraMenu")

	CEikMenuPaneItem::SData sd;

	//LOG1("URL count %d", iURLs.Count());

	for ( TInt i = 0; i< iURLs.Count(); i+=2 )
		{
        sd.iCommandId = 0x2010 + (TInt)(i/2);
		sd.iText.Copy(iURLs[i+1]->Left(30));
		sd.iFlags = 0;
        sd.iCascadeId = 0;
		TRAPD(r,aMenuPane->AddMenuItemL(sd));
		}

	LOG("AddExtraMenu OK")
	}

// -----------------------------------------------------------------------------
// CShoutcastAdapter::HandleCommandL
// When a station is selected from the UI, it is translated into a command which
// is mapped to a URL. The command index is used to lookup the URL.
// -----------------------------------------------------------------------------
//
TBool CShoutcastAdapter::HandleCommandL(
	TInt aCommand )
	{

	LOG("HandleCommandL")

	for ( TInt i=0; i < iURLs.Count(); i+=2 )
		if ( aCommand == 0x2010 + (TInt)(i/2) )
			{
			if ( iState == EPlaying )
				{
				StopL();
				}
			CloseUrl();
			OpenUrlL(i);//this method can leave
			PlayL();
			return ETrue;
			}

	LOG("HandleCommandL OK")

	return EFalse;
	}

// -----------------------------------------------------------------------------
// CShoutcastAdapter::UpdateMenuL
// The menu pane is updated to show only options available in the current state
// of the adapter.
// -----------------------------------------------------------------------------
//
void CShoutcastAdapter::UpdateMenuL(CEikMenuPane* aMenuPane)
	{
	LOG("UpdateMenuL")

    aMenuPane->SetItemDimmed(ES60InternetRadioCmdPlay,   ETrue);
    aMenuPane->SetItemDimmed(ES60InternetRadioCmdStop,   ETrue);
    aMenuPane->SetItemDimmed(ES60InternetRadioCmdChange, ETrue);
	aMenuPane->SetItemDimmed(ES60InternetRadioCmdFileSelect, ETrue);

    switch ( iState )
        {
    	case ENotReady:
        	aMenuPane->SetItemDimmed(ES60InternetRadioCmdChange, EFalse);
        	break;
    	case EReadyToPlay:
        	//aMenuPane->SetItemDimmed(ES60InternetRadioCmdPlay, EFalse);
        	aMenuPane->SetItemDimmed(ES60InternetRadioCmdChange, EFalse);
        	break;
    	case EPlaying:
        	aMenuPane->SetItemDimmed(ES60InternetRadioCmdStop, EFalse);
        	break;
    	default:
        	User::Panic(KShoutcastAdapter, 0);
        	break;
        }

	//the extra menu is available to shoutcast
	aMenuPane->SetItemDimmed(ES60InternetRadioCmdExtra,EFalse);
	aMenuPane->SetItemTextL(ES60InternetRadioCmdExtra,_L("Stations"));

	LOG("UpdateMenuL OK")

	}

// -----------------------------------------------------------------------------
// CShoutcastStream::PlayL
// Starts the stream playback
// -----------------------------------------------------------------------------
//
void CShoutcastAdapter::PlayL()
	{

	LOG("CShoutcastAdapter::PlayL")
	TInt err;

	if ( iState != EReadyToPlay )
		{
		User::Leave(KErrNotReady);
		}

	if ( !iPrimed )
		{
		// The source is not primed, so prime it first
		TRAP(err, iStreamSource->PrimeL());
		if ( err )
			{
			HandleError(err, EOpPrime);
			iStreamSource->Stop();
			CloseUrl();
			return;
			}
		//the actual play command is given when we are connected
		}
	else
		{
		//the shoutcast stream was only paused
		//issue PLay command
		TRAP(err, iStreamSource->PlayL());
		if ( err )
			{
			HandleError(err, EOpPlay);
			iStreamSource->Stop();
			return;
			}
		iState = EPlaying;
		//update metadata
		CMetaDataEntry *mdEntry = NULL;
		TRAP(err, mdEntry = iStreamSource->GetMetaDataEntryL(3));
		if ( !err )
			{
			if ( iObserver )
				{
				iObserver->SetMetadata(3, mdEntry->Value(), ETrue);
				}
			delete mdEntry;
			mdEntry = NULL;
			}
		}
	LOG("CShoutcastAdapter::PlayL OK")

	}


// -----------------------------------------------------------------------------
// CShoutcastAdapter::PauseL
// This implementation pauses the playback but doesn't stop receiving
// streaming data thus allowing the playback to resume quickly.
// -----------------------------------------------------------------------------
//
void CShoutcastAdapter::PauseL()
	{
	LOG("CShoutcastAdapter::PauseL")
    if ( iState == EPlaying )
		{
		iStreamSource->Pause();
		iState = EReadyToPlay;
		TBufC<10> buf=_L("Paused");
		DeleteLabels(EFalse,&buf);
		}
	LOG("CShoutcastAdapter::PauseL OK")
	}

// -----------------------------------------------------------------------------
// CShoutcastAdapter::RecordL
// This is not supported.
// -----------------------------------------------------------------------------
//
void CShoutcastAdapter::RecordL()
    {
	User::Leave(KErrNotSupported);
    }

// -----------------------------------------------------------------------------
// CShoutcastAdapter::StopL
// Stops the playback and the URL is also closed.
// -----------------------------------------------------------------------------
//
void CShoutcastAdapter::StopL()
	{
	LOG("CShoutcastAdapter::StopL")
	if ( iState == EPlaying )
		{
		iStreamSource->Stop();
		iState = EReadyToPlay;
		iPrimed = EFalse;
		TBufC<10> buf=_L("Stopped");
		DeleteLabels(EFalse,&buf);
		}
	LOG("CShoutcastAdapter::StopL OK")
	}

// -----------------------------------------------------------------------------
// CShoutcastAdapter::Identify
// Returned the identity of the adapter.
// -----------------------------------------------------------------------------
//
const TDesC& CShoutcastAdapter::Identify() const
    {
    return KShoutcastAdapter;
    }


// -----------------------------------------------------------------------------
// CShoutcastAdapter::SupportMetadata
//
// -----------------------------------------------------------------------------
//
TInt CShoutcastAdapter::SupportMetadata() const
	{
	return iNrMetadata;
	}

// -----------------------------------------------------------------------------
// CShoutcastAdapter::TogglePlayPause
// Toggles play and stop.
// -----------------------------------------------------------------------------
//
void CShoutcastAdapter::TogglePlayPause()
	{
	if ( iState == EReadyToPlay )
		{
		PlayL();
		}
	else if ( iState == EPlaying )
		{
		PauseL();
		}
	}

// -----------------------------------------------------------------------------
// CShoutcastAdapter::HandleEvent
// Handle events from the shoutcast stream.
// -----------------------------------------------------------------------------
//
void CShoutcastAdapter::HandleEvent(
	TUid aEvent,
	TInt aError)
	{
	TInt r;
	LOG2("HandleEvent: We got an Event: %x %d", aEvent, aError);

	// Metadata update event
	if ( aEvent == TUid::Uid(KShoutcastStreamUid) && aError > 0x0100 && aError < 0x0200 )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -