From 6b6c0b120f3275be6bd9dbb26480f8f1df355e00 Mon Sep 17 00:00:00 2001 From: Mark Hung Date: Sun, 27 Jan 2019 13:41:34 +0800 Subject: tdf#44223 allow slideshow to play embedded media. Implement MediaFileManager that create the temp media file for package urls when making slideshow. Change-Id: I10a5ddc405928b4322ad72eb603508faf25bf0db Reviewed-on: https://gerrit.libreoffice.org/67209 Tested-by: Jenkins Reviewed-by: Mark Hung --- .../engine/animationnodes/animationaudionode.cxx | 3 +- slideshow/source/engine/slide/slideimpl.cxx | 6 ++- slideshow/source/engine/slideshowcontext.cxx | 2 + slideshow/source/engine/slideshowimpl.cxx | 46 +++++++++++++++++++++- slideshow/source/engine/soundplayer.cxx | 17 +++++--- slideshow/source/inc/mediafilemanager.hxx | 36 +++++++++++++++++ slideshow/source/inc/slide.hxx | 2 + slideshow/source/inc/slideshowcontext.hxx | 6 +++ slideshow/source/inc/soundplayer.hxx | 11 +++++- 9 files changed, 119 insertions(+), 10 deletions(-) create mode 100644 slideshow/source/inc/mediafilemanager.hxx (limited to 'slideshow') diff --git a/slideshow/source/engine/animationnodes/animationaudionode.cxx b/slideshow/source/engine/animationnodes/animationaudionode.cxx index 4aa02f5da7dd..b024de24de53 100644 --- a/slideshow/source/engine/animationnodes/animationaudionode.cxx +++ b/slideshow/source/engine/animationnodes/animationaudionode.cxx @@ -152,7 +152,8 @@ void AnimationAudioNode::createPlayer() const { mpPlayer = SoundPlayer::create( getContext().mrEventMultiplexer, maSoundURL, - getContext().mxComponentContext ); + getContext().mxComponentContext, + getContext().mrMediaFileManager); } catch( lang::NoSupportException& ) { diff --git a/slideshow/source/engine/slide/slideimpl.cxx b/slideshow/source/engine/slide/slideimpl.cxx index 931eea2211b7..3d01f4dfbef4 100644 --- a/slideshow/source/engine/slide/slideimpl.cxx +++ b/slideshow/source/engine/slide/slideimpl.cxx @@ -90,6 +90,7 @@ public: ActivitiesQueue& rActivitiesQueue, UserEventQueue& rUserEventQueue, CursorManager& rCursorManager, + MediaFileManager& rMediaFileManager, const UnoViewContainer& rViewContainer, const uno::Reference& xContext, const ShapeEventListenerMap& rShapeListenerMap, @@ -310,6 +311,7 @@ SlideImpl::SlideImpl( const uno::Reference< drawing::XDrawPage >& xDra ActivitiesQueue& rActivitiesQueue, UserEventQueue& rUserEventQueue, CursorManager& rCursorManager, + MediaFileManager& rMediaFileManager, const UnoViewContainer& rViewContainer, const uno::Reference< uno::XComponentContext >& xComponentContext, const ShapeEventListenerMap& rShapeListenerMap, @@ -340,6 +342,7 @@ SlideImpl::SlideImpl( const uno::Reference< drawing::XDrawPage >& xDra rActivitiesQueue, rUserEventQueue, *this, + rMediaFileManager, rViewContainer, xComponentContext ), mrCursorManager( rCursorManager ), @@ -1096,6 +1099,7 @@ SlideSharedPtr createSlide( const uno::Reference< drawing::XDrawPage >& ActivitiesQueue& rActivitiesQueue, UserEventQueue& rUserEventQueue, CursorManager& rCursorManager, + MediaFileManager& rMediaFileManager, const UnoViewContainer& rViewContainer, const uno::Reference< uno::XComponentContext >& xComponentContext, const ShapeEventListenerMap& rShapeListenerMap, @@ -1110,7 +1114,7 @@ SlideSharedPtr createSlide( const uno::Reference< drawing::XDrawPage >& std::shared_ptr pRet( new SlideImpl( xDrawPage, xDrawPages, xRootNode, rEventQueue, rEventMultiplexer, rScreenUpdater, rActivitiesQueue, rUserEventQueue, - rCursorManager, rViewContainer, + rCursorManager, rMediaFileManager, rViewContainer, xComponentContext, rShapeListenerMap, rShapeCursorMap, rPolyPolygonVector, rUserPaintColor, dUserPaintStrokeWidth, bUserPaintEnabled, diff --git a/slideshow/source/engine/slideshowcontext.cxx b/slideshow/source/engine/slideshowcontext.cxx index 856c4d979c01..94d8c83cd96b 100644 --- a/slideshow/source/engine/slideshowcontext.cxx +++ b/slideshow/source/engine/slideshowcontext.cxx @@ -44,6 +44,7 @@ SlideShowContext::SlideShowContext( SubsettableShapeManagerSharedPtr& rSubsettab ActivitiesQueue& rActivitiesQueue, UserEventQueue& rUserEventQueue, CursorManager& rCursorManager, + MediaFileManager& rMediaFileManager, const UnoViewContainer& rViewContainer, const uno::Reference< uno::XComponentContext>& rComponentContext ) : @@ -54,6 +55,7 @@ SlideShowContext::SlideShowContext( SubsettableShapeManagerSharedPtr& rSubsettab mrActivitiesQueue( rActivitiesQueue ), mrUserEventQueue( rUserEventQueue ), mrCursorManager( rCursorManager ), + mrMediaFileManager( rMediaFileManager ), mrViewContainer( rViewContainer ), mxComponentContext( rComponentContext ) {} diff --git a/slideshow/source/engine/slideshowimpl.cxx b/slideshow/source/engine/slideshowimpl.cxx index b2437e4b147d..177ff07dfb1b 100644 --- a/slideshow/source/engine/slideshowimpl.cxx +++ b/slideshow/source/engine/slideshowimpl.cxx @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -68,6 +69,7 @@ #include #include #include +#include #include #include @@ -78,6 +80,7 @@ #include #include #include +#include #include #include #include @@ -209,6 +212,7 @@ typedef ::std::map< css::uno::Reference< class SlideShowImpl : private cppu::BaseMutex, public CursorManager, + public MediaFileManager, public SlideShowImplBase { public: @@ -271,6 +275,9 @@ public: */ bool handleAnimationEvent( const AnimationNodeSharedPtr& rNode ); + /** Obtain a MediaTempFile for the specified url. */ + virtual std::shared_ptr getMediaTempFile(const OUString& aUrl) override; + private: // XSlideShow: virtual sal_Bool SAL_CALL nextEffect() override; @@ -460,6 +467,8 @@ private: uno::Reference mxPrefetchSlide; /// save the XDrawPagesSupplier to retrieve polygons uno::Reference mxDrawPagesSupplier; + /// Used by MediaFileManager, for media files with package url. + uno::Reference mxSBD; /// slide animation to be prefetched: uno::Reference mxPrefetchAnimationNode; @@ -572,6 +581,7 @@ SlideShowImpl::SlideShowImpl( mpPrefetchSlide(), mxPrefetchSlide(), mxDrawPagesSupplier(), + mxSBD(), mxPrefetchAnimationNode(), mnCurrentCursor(awt::SystemPointer::ARROW), mnWaitSymbolRequestCount(0), @@ -710,7 +720,7 @@ SoundPlayerSharedPtr SlideShowImpl::resetSlideTransitionSound( const uno::Any& r try { mpCurrentSlideTransitionSound = SoundPlayer::create( - maEventMultiplexer, url, mxComponentContext ); + maEventMultiplexer, url, mxComponentContext, *this); mpCurrentSlideTransitionSound->setPlaybackLoop( bLoopSound ); } catch (lang::NoSupportException const&) @@ -894,6 +904,7 @@ SlideSharedPtr SlideShowImpl::makeSlide( maActivitiesQueue, maUserEventQueue, *this, + *this, maViewContainer, mxComponentContext, maShapeEventListeners, @@ -1055,6 +1066,7 @@ void SlideShowImpl::displaySlide( DBG_TESTSOLARMUTEX(); mxDrawPagesSupplier = xDrawPages; + mxSBD = uno::Reference(mxDrawPagesSupplier, uno::UNO_QUERY); stopShow(); // MUST call that: results in // maUserEventQueue.clear(). What's more, @@ -1686,6 +1698,7 @@ sal_Bool SlideShowImpl::setProperty( beans::PropertyValue const& rProperty ) maActivitiesQueue, maUserEventQueue, *this, + *this, maViewContainer, mxComponentContext) ); } @@ -2332,6 +2345,37 @@ bool SlideShowImpl::handleAnimationEvent( const AnimationNodeSharedPtr& rNode ) return true; } +std::shared_ptr SlideShowImpl::getMediaTempFile(const OUString& aUrl) +{ + std::shared_ptr aRet; + + if (!mxSBD.is()) + return aRet; + + comphelper::LifecycleProxy aProxy; + uno::Reference xStream = + comphelper::OStorageHelper::GetStreamAtPackageURL(mxSBD->getDocumentStorage(), aUrl, + css::embed::ElementModes::READ, aProxy); + + uno::Reference xInStream = xStream->getInputStream(); + if (xInStream.is()) + { + sal_Int32 nLastDot = aUrl.lastIndexOf('.'); + sal_Int32 nLastSlash = aUrl.lastIndexOf('/'); + OUString sDesiredExtension; + if (nLastDot > nLastSlash && nLastDot+1 < aUrl.getLength()) + sDesiredExtension = aUrl.copy(nLastDot); + + OUString sTempUrl; + if (::avmedia::CreateMediaTempFile(xInStream, sTempUrl, sDesiredExtension)) + aRet.reset(new avmedia::MediaTempFile(sTempUrl)); + + xInStream->closeInput(); + } + + return aRet; +} + //===== FrameSynchronization ================================================== FrameSynchronization::FrameSynchronization (const double nFrameDuration) diff --git a/slideshow/source/engine/soundplayer.cxx b/slideshow/source/engine/soundplayer.cxx index 2f19fca124b9..505478cd3e33 100644 --- a/slideshow/source/engine/soundplayer.cxx +++ b/slideshow/source/engine/soundplayer.cxx @@ -31,7 +31,7 @@ #include #include - +#include #include #include @@ -48,12 +48,14 @@ namespace slideshow std::shared_ptr SoundPlayer::create( EventMultiplexer & rEventMultiplexer, const OUString& rSoundURL, - const uno::Reference< uno::XComponentContext>& rComponentContext ) + const uno::Reference< uno::XComponentContext>& rComponentContext, + MediaFileManager& rMediaFileManager) { std::shared_ptr pPlayer( new SoundPlayer( rEventMultiplexer, rSoundURL, - rComponentContext ) ); + rComponentContext, + rMediaFileManager) ); rEventMultiplexer.addPauseHandler( pPlayer ); pPlayer->mThis = pPlayer; return pPlayer; @@ -86,7 +88,8 @@ namespace slideshow SoundPlayer::SoundPlayer( EventMultiplexer & rEventMultiplexer, const OUString& rSoundURL, - const uno::Reference< uno::XComponentContext>& rComponentContext ) + const uno::Reference< uno::XComponentContext>& rComponentContext, + MediaFileManager& rMediaFileManager) : mrEventMultiplexer(rEventMultiplexer), mThis(), mxPlayer() @@ -96,7 +99,11 @@ namespace slideshow try { - const INetURLObject aURL( rSoundURL ); + if (rSoundURL.startsWithIgnoreAsciiCase("vnd.sun.star.Package:")) + { + mpMediaTempFile = rMediaFileManager.getMediaTempFile(rSoundURL); + } + const INetURLObject aURL( mpMediaTempFile ? mpMediaTempFile->m_TempFileURL : rSoundURL ); mxPlayer.set( avmedia::MediaWindow::createPlayer( aURL.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous ), ""/*TODO!*/ ), uno::UNO_QUERY); diff --git a/slideshow/source/inc/mediafilemanager.hxx b/slideshow/source/inc/mediafilemanager.hxx new file mode 100644 index 000000000000..1c6bee62e78d --- /dev/null +++ b/slideshow/source/inc/mediafilemanager.hxx @@ -0,0 +1,36 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_MEDIAFILEMANAGER_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_MEDIAFILEMANAGER_HXX + +#include +#include + +namespace avmedia +{ +struct MediaTempFile; +} + +namespace slideshow +{ +namespace internal +{ +class MediaFileManager +{ +public: + virtual ~MediaFileManager(){}; + virtual std::shared_ptr getMediaTempFile(const OUString& aUrl) = 0; +}; +} +} +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_MEDIAFILEMANAGER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/slide.hxx b/slideshow/source/inc/slide.hxx index 8715931bf33b..cce3edbeee4e 100644 --- a/slideshow/source/inc/slide.hxx +++ b/slideshow/source/inc/slide.hxx @@ -153,6 +153,7 @@ namespace slideshow class EventQueue; class CursorManager; + class MediaFileManager; class EventMultiplexer; class ActivitiesQueue; class UserEventQueue; @@ -195,6 +196,7 @@ namespace slideshow ActivitiesQueue& rActivitiesQueue, UserEventQueue& rUserEventQueue, CursorManager& rCursorManager, + MediaFileManager& rMediaFileManager, const UnoViewContainer& rViewContainer, const css::uno::Reference< css::uno::XComponentContext >& xContext, const ShapeEventListenerMap& rShapeListenerMap, diff --git a/slideshow/source/inc/slideshowcontext.hxx b/slideshow/source/inc/slideshowcontext.hxx index 7c1907321760..dee43ba0a8b9 100644 --- a/slideshow/source/inc/slideshowcontext.hxx +++ b/slideshow/source/inc/slideshowcontext.hxx @@ -41,6 +41,7 @@ namespace slideshow class ScreenUpdater; class UnoViewContainer; class CursorManager; + class MediaFileManager; class SubsettableShapeManager; /** Common arguments for slideshow objects. @@ -72,6 +73,9 @@ namespace slideshow Activities queue, where repeating activities are to be scheduled. + @param rMediaFileManager + To handle media file with package urls. + @param rUserEventQueue User event queue @@ -88,6 +92,7 @@ namespace slideshow ActivitiesQueue& rActivitiesQueue, UserEventQueue& rUserEventQueue, CursorManager& rCursorManager, + MediaFileManager& rMediaFileManager, const UnoViewContainer& rViewContainer, const css::uno::Reference< css::uno::XComponentContext>& rComponentContext ); void dispose(); @@ -99,6 +104,7 @@ namespace slideshow ActivitiesQueue& mrActivitiesQueue; UserEventQueue& mrUserEventQueue; CursorManager& mrCursorManager; + MediaFileManager& mrMediaFileManager; const UnoViewContainer& mrViewContainer; css::uno::Reference< css::uno::XComponentContext> mxComponentContext; }; diff --git a/slideshow/source/inc/soundplayer.hxx b/slideshow/source/inc/soundplayer.hxx index 82af088af462..ea496d88b8cc 100644 --- a/slideshow/source/inc/soundplayer.hxx +++ b/slideshow/source/inc/soundplayer.hxx @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -39,6 +40,8 @@ namespace slideshow { namespace internal { + class MediaFileManager; + /** Little class that plays a sound from a URL. TODO: Must be explicitly disposed (as long as enable_shared_ptr_from_this @@ -64,7 +67,8 @@ namespace slideshow static ::std::shared_ptr create( EventMultiplexer & rEventMultiplexer, const OUString& rSoundURL, - const css::uno::Reference< css::uno::XComponentContext>& rComponentContext ); + const css::uno::Reference< css::uno::XComponentContext>& rComponentContext, + MediaFileManager& rMediaFileManager); virtual ~SoundPlayer() override; @@ -92,12 +96,15 @@ namespace slideshow SoundPlayer( EventMultiplexer & rEventMultiplexer, const OUString& rSoundURL, - const css::uno::Reference< css::uno::XComponentContext>& rComponentContext ); + const css::uno::Reference< css::uno::XComponentContext>& rComponentContext, + MediaFileManager & rMediaFileManager); EventMultiplexer & mrEventMultiplexer; // TODO(Q3): obsolete when boost::enable_shared_ptr_from_this // is available ::std::shared_ptr mThis; + // Temp file for pakcage url. + ::std::shared_ptr<::avmedia::MediaTempFile> mpMediaTempFile; css::uno::Reference< css::media::XPlayer > mxPlayer; }; -- cgit