1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_slideshow.hxx"
26 
27 #include <canvas/debug.hxx>
28 #include <tools/diagnose_ex.h>
29 #include <canvas/verbosetrace.hxx>
30 
31 #include <comphelper/anytostring.hxx>
32 #include <cppuhelper/exc_hlp.hxx>
33 
34 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
35 #include <com/sun/star/lang/NoSupportException.hpp>
36 #include <com/sun/star/lang/XComponent.hdl>
37 
38 #include <tools/urlobj.hxx>
39 
40 #include <avmedia/mediawindow.hxx>
41 
42 #include "soundplayer.hxx"
43 
44 #include <algorithm>
45 
46 using namespace ::com::sun::star;
47 
48 
49 namespace slideshow
50 {
51     namespace internal
52     {
53         // TODO(Q3): Move the whole SoundPlayer class to avmedia.
54 
create(EventMultiplexer & rEventMultiplexer,const::rtl::OUString & rSoundURL,const uno::Reference<uno::XComponentContext> & rComponentContext)55         boost::shared_ptr<SoundPlayer> SoundPlayer::create(
56             EventMultiplexer & rEventMultiplexer,
57             const ::rtl::OUString& rSoundURL,
58             const uno::Reference< uno::XComponentContext>&	rComponentContext )
59         {
60             boost::shared_ptr<SoundPlayer> pPlayer(
61                 new SoundPlayer( rEventMultiplexer,
62                                  rSoundURL,
63                                  rComponentContext ) );
64             rEventMultiplexer.addPauseHandler( pPlayer );
65             pPlayer->mThis = pPlayer;
66             return pPlayer;
67         }
68 
handlePause(bool bPauseShow)69         bool SoundPlayer::handlePause( bool bPauseShow )
70         {
71             return bPauseShow ? stopPlayback() : startPlayback();
72         }
73 
dispose()74         void SoundPlayer::dispose()
75         {
76             if( mThis )
77             {
78                 mrEventMultiplexer.removePauseHandler( mThis );
79                 mThis.reset();
80             }
81 
82 			if( mxPlayer.is() )
83             {
84 				mxPlayer->stop();
85 				uno::Reference<lang::XComponent> xComponent(
86                     mxPlayer, uno::UNO_QUERY );
87 				if( xComponent.is() )
88 					xComponent->dispose();
89                 mxPlayer.clear();
90 			}
91         }
92 
SoundPlayer(EventMultiplexer & rEventMultiplexer,const::rtl::OUString & rSoundURL,const uno::Reference<uno::XComponentContext> & rComponentContext)93         SoundPlayer::SoundPlayer(
94             EventMultiplexer & rEventMultiplexer,
95             const ::rtl::OUString& rSoundURL,
96             const uno::Reference< uno::XComponentContext>&	rComponentContext )
97             : mrEventMultiplexer(rEventMultiplexer),
98               mThis(),
99               mxPlayer()
100         {
101             ENSURE_OR_THROW( rComponentContext.is(),
102                               "SoundPlayer::SoundPlayer(): Invalid component context" );
103 
104             try
105             {
106         		const INetURLObject aURL( rSoundURL );
107                 mxPlayer.set( avmedia::MediaWindow::createPlayer(
108                                 aURL.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS ) ),
109                                 uno::UNO_QUERY);
110             }
111             catch( uno::RuntimeException& )
112             {
113                 throw;
114             }
115             catch( uno::Exception& )
116             {
117             }
118 
119             if( !mxPlayer.is() )
120                 throw lang::NoSupportException(
121                     rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
122                                        "No sound support for ") ) + rSoundURL,
123                     uno::Reference<uno::XInterface>() );
124         }
125 
~SoundPlayer()126         SoundPlayer::~SoundPlayer()
127         {
128             try
129             {
130                 dispose();
131             }
132             catch (uno::Exception &) {
133                 OSL_ENSURE( false, rtl::OUStringToOString(
134                                 comphelper::anyToString(
135                                     cppu::getCaughtException() ),
136                                 RTL_TEXTENCODING_UTF8 ).getStr() );
137             }
138         }
139 
getDuration() const140         double SoundPlayer::getDuration() const
141         {
142             if( !mxPlayer.is() )
143                 return 0.0;
144 
145             const double nDuration( mxPlayer->getDuration() );
146             if( mxPlayer->isPlaying() )
147                 return ::std::max( 0.0,
148                                    nDuration - mxPlayer->getMediaTime() );
149             else
150                 return nDuration;
151         }
152 
startPlayback()153         bool SoundPlayer::startPlayback()
154         {
155             if( !mxPlayer.is() )
156                 return false;
157 
158             if( mxPlayer->isPlaying() )
159                 mxPlayer->stop();
160 
161             mxPlayer->start();
162             return true;
163         }
164 
stopPlayback()165         bool SoundPlayer::stopPlayback()
166         {
167             if( mxPlayer.is() )
168                 mxPlayer->stop();
169 
170             return true;
171         }
172 
setPlaybackLoop(bool bLoop)173 		void SoundPlayer::setPlaybackLoop( bool bLoop )
174 		{
175 			if( mxPlayer.is() )
176 				mxPlayer->setPlaybackLoop( bLoop );
177 		}
178     }
179 }
180