diff options
author | Michael Stahl <mstahl@redhat.com> | 2011-12-03 00:10:10 +0100 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2011-12-03 00:48:16 +0100 |
commit | 59307a7164e35396f34bf621ad7e9d2f265b1c7f (patch) | |
tree | 3282a95522303ff1553e0b4f3fda8f1978ce4830 /avmedia | |
parent | 116ad02ae89a0036a223ef943352587119a47f65 (diff) |
actually play embedded media:
In order to do this, the media is written to a temp file by
avmedia::MediaWindowBaseImpl. This requires some rather ugly hacks to
transport the Storage that contains the media to the avmedia stuff,
including adding a XModel reference to avmedia::MediaItem.
Diffstat (limited to 'avmedia')
-rw-r--r-- | avmedia/inc/avmedia/mediaitem.hxx | 6 | ||||
-rw-r--r-- | avmedia/source/framework/mediacontrol.cxx | 2 | ||||
-rw-r--r-- | avmedia/source/framework/mediaitem.cxx | 19 | ||||
-rw-r--r-- | avmedia/source/viewer/mediawindow.cxx | 2 | ||||
-rw-r--r-- | avmedia/source/viewer/mediawindowbase_impl.cxx | 127 | ||||
-rw-r--r-- | avmedia/source/viewer/mediawindowbase_impl.hxx | 20 |
6 files changed, 156 insertions, 20 deletions
diff --git a/avmedia/inc/avmedia/mediaitem.hxx b/avmedia/inc/avmedia/mediaitem.hxx index a1908105e235..0e4af5c07507 100644 --- a/avmedia/inc/avmedia/mediaitem.hxx +++ b/avmedia/inc/avmedia/mediaitem.hxx @@ -114,8 +114,12 @@ public: void setZoom( ::com::sun::star::media::ZoomLevel eZoom ); ::com::sun::star::media::ZoomLevel getZoom() const; - void setURL( const ::rtl::OUString& rURL ); + void setURL( const ::rtl::OUString& rURL, + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel> + const& xModel); const ::rtl::OUString& getURL() const; + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel> + getModel() const; private: diff --git a/avmedia/source/framework/mediacontrol.cxx b/avmedia/source/framework/mediacontrol.cxx index 291906992911..ceb375ed24f8 100644 --- a/avmedia/source/framework/mediacontrol.cxx +++ b/avmedia/source/framework/mediacontrol.cxx @@ -506,7 +506,7 @@ IMPL_LINK( MediaControl, implSelectHdl, ToolBox*, p ) ::avmedia::MediaWindow::executeFormatErrorBox( this ); else { - aExecItem.setURL( aURL ); + aExecItem.setURL( aURL, 0 ); aExecItem.setState( MEDIASTATE_PLAY ); } } diff --git a/avmedia/source/framework/mediaitem.cxx b/avmedia/source/framework/mediaitem.cxx index afda0ab81651..d38548afc561 100644 --- a/avmedia/source/framework/mediaitem.cxx +++ b/avmedia/source/framework/mediaitem.cxx @@ -27,6 +27,8 @@ ************************************************************************/ #include <avmedia/mediaitem.hxx> + +#include <cppuhelper/weakref.hxx> #include <com/sun/star/uno/Sequence.hxx> #include <com/sun/star/beans/XPropertySet.hpp> @@ -59,6 +61,8 @@ TYPEINIT1_AUTOFACTORY( MediaItem, ::SfxPoolItem ); struct MediaItem::Impl { ::rtl::OUString m_URL; + // store a weak ref to the model so we can get at embedded media + uno::WeakReference<frame::XModel> m_wModel; sal_uInt32 m_nMaskSet; MediaState m_eState; double m_fTime; @@ -81,6 +85,7 @@ struct MediaItem::Impl } Impl(Impl const& rOther) : m_URL( rOther.m_URL ) + , m_wModel( rOther.m_wModel ) , m_nMaskSet( rOther.m_nMaskSet ) , m_eState( rOther.m_eState ) , m_fTime( rOther.m_fTime ) @@ -207,7 +212,7 @@ void MediaItem::merge( const MediaItem& rMediaItem ) const sal_uInt32 nMaskSet = rMediaItem.getMaskSet(); if( AVMEDIA_SETMASK_URL & nMaskSet ) - setURL( rMediaItem.getURL() ); + setURL( rMediaItem.getURL(), rMediaItem.getModel() ); if( AVMEDIA_SETMASK_STATE & nMaskSet ) setState( rMediaItem.getState() ); @@ -240,10 +245,15 @@ sal_uInt32 MediaItem::getMaskSet() const //------------------------------------------------------------------------ -void MediaItem::setURL( const ::rtl::OUString& rURL ) +void MediaItem::setURL( const ::rtl::OUString& rURL, + uno::Reference<frame::XModel> const & xModel) { m_pImpl->m_URL = rURL; m_pImpl->m_nMaskSet |= AVMEDIA_SETMASK_URL; + if (xModel.is()) + { + m_pImpl->m_wModel = xModel; + } } //------------------------------------------------------------------------ @@ -253,6 +263,11 @@ const ::rtl::OUString& MediaItem::getURL() const return m_pImpl->m_URL; } +uno::Reference<frame::XModel> MediaItem::getModel() const +{ + return m_pImpl->m_wModel; +} + //------------------------------------------------------------------------ void MediaItem::setState( MediaState eState ) diff --git a/avmedia/source/viewer/mediawindow.cxx b/avmedia/source/viewer/mediawindow.cxx index f063526d53e5..9a3cab2da97e 100644 --- a/avmedia/source/viewer/mediawindow.cxx +++ b/avmedia/source/viewer/mediawindow.cxx @@ -73,7 +73,7 @@ MediaWindow::~MediaWindow() void MediaWindow::setURL( const ::rtl::OUString& rURL ) { if( mpImpl ) - mpImpl->setURL( rURL ); + mpImpl->setURL( rURL, uno::Reference<frame::XModel>() ); } // ------------------------------------------------------------------------- diff --git a/avmedia/source/viewer/mediawindowbase_impl.cxx b/avmedia/source/viewer/mediawindowbase_impl.cxx index c6b46aff133d..d9e8fa60342a 100644 --- a/avmedia/source/viewer/mediawindowbase_impl.cxx +++ b/avmedia/source/viewer/mediawindowbase_impl.cxx @@ -32,11 +32,16 @@ #include "mediawindow.hrc" #include <rtl/oustringostreaminserter.hxx> #include <sal/log.hxx> +#include <osl/file.hxx> #include <tools/urlobj.hxx> +#include <ucbhelper/content.hxx> #include <comphelper/processfactory.hxx> +#include <comphelper/storagehelper.hxx> #include <com/sun/star/lang/XMultiServiceFactory.hpp> -#include <com/sun/star/media/XManager.hpp> #include <com/sun/star/lang/XComponent.hdl> +#include <com/sun/star/media/XManager.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/document/XStorageBasedDocument.hpp> #define MEDIA_TIMER_TIMEOUT 100 @@ -49,8 +54,9 @@ namespace avmedia { namespace priv { // ----------------------- -MediaWindowBaseImpl::MediaWindowBaseImpl( MediaWindow* pMediaWindow ) : - mpMediaWindow( pMediaWindow ) +MediaWindowBaseImpl::MediaWindowBaseImpl( MediaWindow* pMediaWindow ) + : mpTempFileURL(0) + , mpMediaWindow( pMediaWindow ) { } @@ -101,13 +107,90 @@ uno::Reference< media::XPlayer > MediaWindowBaseImpl::createPlayer( const ::rtl: } // --------------------------------------------------------------------- +void MediaWindowBaseImpl::cleanupTempFile() +{ + if (mpTempFileURL) + { + ::osl::File::remove(*mpTempFileURL); + delete mpTempFileURL; + mpTempFileURL = 0; + } +} -void MediaWindowBaseImpl::setURL( const ::rtl::OUString& rURL ) +bool +MediaWindowBaseImpl::initPackageURL(::rtl::OUString const & rURL, + uno::Reference<frame::XModel> const& xModel) { - if( rURL != getURL() ) + uno::Reference<document::XStorageBasedDocument> const xSBD( + xModel, uno::UNO_QUERY); + if (!xSBD.is()) + { + SAL_WARN("avmedia", "cannot get model"); + return false; + } + uno::Reference<embed::XStorage> const xStorage( + xSBD->getDocumentStorage()); + if (!xStorage.is()) + { + SAL_WARN("avmedia", "cannot get storage"); + return false; + } + ::comphelper::LifecycleProxy proxy; + uno::Reference<io::XInputStream> xInStream; + try { + uno::Reference<io::XStream> const xStream( + ::comphelper::OStorageHelper::GetStreamAtPackageURL( + xStorage, rURL, embed::ElementModes::READ, proxy)); + xInStream = (xStream.is()) ? xStream->getInputStream() : 0; + } + catch (container::NoSuchElementException const&) + { + SAL_INFO("avmedia", "not found: '" << ::rtl::OUString(rURL) << "'"); + return false; + } + catch (uno::Exception const& e) + { + SAL_WARN("avmedia", "exception: '" << e.Message << "'"); + return false; + } + if (!xInStream.is()) { - INetURLObject aURL( maFileURL = rURL ); + SAL_WARN("avmedia", "no stream?"); + return false; + } + + mpTempFileURL = new ::rtl::OUString; + ::osl::FileBase::RC const err = + ::osl::FileBase::createTempFile(0, 0, mpTempFileURL); + if (::osl::FileBase::E_None != err) + { + SAL_INFO("avmedia", "cannot create temp file"); + delete mpTempFileURL; + mpTempFileURL = 0; + return false; + } + try + { + ::ucbhelper::Content tempContent(*mpTempFileURL, + uno::Reference<ucb::XCommandEnvironment>()); + tempContent.writeStream(xInStream, true); // copy stream to file + } + catch (uno::Exception const& e) + { + SAL_WARN("avmedia", "exception: '" << e.Message << "'"); + return false; + } + return true; +} + +static char const s_PkgScheme[] = "vnd.sun.star.Package:"; + +void MediaWindowBaseImpl::setURL( const ::rtl::OUString& rURL, + uno::Reference<frame::XModel> const& xModel ) +{ + if( rURL != getURL() ) + { if( mxPlayer.is() ) mxPlayer->stop(); @@ -118,11 +201,32 @@ void MediaWindowBaseImpl::setURL( const ::rtl::OUString& rURL ) } mxPlayer.clear(); + cleanupTempFile(); - if( aURL.GetProtocol() != INET_PROT_NOT_VALID ) - maFileURL = aURL.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS ); + bool bSuccess(true); + if (0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( + rURL.getStr(), rURL.getLength(), + s_PkgScheme, SAL_N_ELEMENTS(s_PkgScheme) - 1)) + { + bSuccess = initPackageURL(rURL, xModel); - mxPlayer = createPlayer( maFileURL ); + maFileURL = (bSuccess) ? rURL : ::rtl::OUString(); + } + else + { + INetURLObject aURL( rURL ); + + if (aURL.GetProtocol() != INET_PROT_NOT_VALID) + maFileURL = aURL.GetMainURL(INetURLObject::DECODE_UNAMBIGUOUS); + else + maFileURL = rURL; + } + + if (bSuccess) + { + mxPlayer = createPlayer( + (mpTempFileURL) ? *mpTempFileURL : maFileURL ); + } onURLChanged(); } } @@ -200,6 +304,7 @@ void MediaWindowBaseImpl::cleanUp() mxPlayer.clear(); } + cleanupTempFile(); mpMediaWindow = NULL; } @@ -376,7 +481,7 @@ void MediaWindowBaseImpl::updateMediaItem( MediaItem& rItem ) const rItem.setMute( isMute() ); rItem.setVolumeDB( getVolumeDB() ); rItem.setZoom( getZoom() ); - rItem.setURL( getURL() ); + rItem.setURL( getURL(), 0 ); } // ------------------------------------------------------------------------- @@ -387,7 +492,7 @@ void MediaWindowBaseImpl::executeMediaItem( const MediaItem& rItem ) // set URL first if( nMaskSet & AVMEDIA_SETMASK_URL ) - setURL( rItem.getURL() ); + setURL( rItem.getURL(), rItem.getModel() ); // set different states next if( nMaskSet & AVMEDIA_SETMASK_TIME ) diff --git a/avmedia/source/viewer/mediawindowbase_impl.hxx b/avmedia/source/viewer/mediawindowbase_impl.hxx index 1aa615a5986f..935b88a2aa65 100644 --- a/avmedia/source/viewer/mediawindowbase_impl.hxx +++ b/avmedia/source/viewer/mediawindowbase_impl.hxx @@ -26,13 +26,19 @@ * ************************************************************************/ -#ifndef _AVMEDIA_MEDIAWINDOWBASE_IMPL_HXX -#define _AVMEDIA_MEDIAWINDOWBASE_IMPL_HXX +#ifndef AVMEDIA_MEDIAWINDOWBASE_IMPL_HXX +#define AVMEDIA_MEDIAWINDOWBASE_IMPL_HXX #include <avmedia/mediawindow.hxx> + #include <com/sun/star/media/XPlayer.hpp> #include <com/sun/star/media/XPlayerWindow.hpp> + +namespace com { namespace sun { namespace star { + namespace frame { class XModel; } +}}} // namespace com::sun::star + namespace avmedia { namespace priv @@ -64,9 +70,10 @@ namespace avmedia static ::com::sun::star::uno::Reference< ::com::sun::star::media::XPlayer > createPlayer( const ::rtl::OUString& rURL); - public: + void setURL( const ::rtl::OUString& rURL, + ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XModel> const& wModel); - void setURL( const ::rtl::OUString& rURL ); const ::rtl::OUString& getURL() const; bool isValid() const; @@ -121,8 +128,13 @@ namespace avmedia ::com::sun::star::uno::Reference< ::com::sun::star::media::XPlayerWindow > getPlayerWindow() const; private: + void cleanupTempFile(); + bool initPackageURL( const ::rtl::OUString& rPath, + ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XModel> const& wModel); ::rtl::OUString maFileURL; + ::rtl::OUString * mpTempFileURL; ::com::sun::star::uno::Reference< ::com::sun::star::media::XPlayer > mxPlayer; ::com::sun::star::uno::Reference< ::com::sun::star::media::XPlayerWindow > mxPlayerWindow; MediaWindow* mpMediaWindow; |