summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <michael.stahl@allotropia.de>2023-04-05 11:50:44 +0200
committerMichael Stahl <michael.stahl@allotropia.de>2023-04-05 14:34:51 +0200
commita5225ba82e94a549f44420f56a7cb9d7906561cc (patch)
tree084be80b91028e3bfbe8cd5e3b50ba97fa8b516d
parent8b4af1eb0549b6832361da85ddaa1e13be34ec76 (diff)
avmedia,*: guess the mime type of media files based on file name
.. at least for the most popular types, and do it automatically in MediaItem::setURL(). This should work in practice in most cases and is much simpler than adding some type detection or calling into platform dependent avmedia backends. Remove the parameter that was only ever set to "application/vnd.sun.star.media" anyway, the same value that would be used if it's missing. Stop using that silly type for everything, only use it when guessing fails. In case an ODF document is loaded, it will use the mime type loaded from the file (see setting of MediaMimeType in SdXMLPluginShapeContext) and not guess it because that would require updating the entry in manifest.xml as well. Change-Id: I8ce29cf7425678ae11dda1d8c875be818f8623af Reviewed-on: https://gerrit.libreoffice.org/c/core/+/150049 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
-rw-r--r--avmedia/source/framework/mediaitem.cxx9
-rw-r--r--avmedia/source/inc/mediamisc.hxx5
-rw-r--r--avmedia/source/viewer/mediawindow_impl.cxx7
-rw-r--r--comphelper/source/misc/graphicmimetype.cxx68
-rw-r--r--include/comphelper/mediamimetype.hxx30
-rw-r--r--include/svx/svdomedia.hxx2
-rw-r--r--oox/source/export/drawingml.cxx5
-rw-r--r--sd/source/ui/inc/View.hxx2
-rw-r--r--sd/source/ui/view/sdview4.cxx8
-rw-r--r--svx/source/svdraw/svdomedia.cxx4
-rw-r--r--xmloff/source/draw/ximpshap.cxx5
-rw-r--r--xmloff/source/text/XMLTextFrameContext.cxx3
12 files changed, 126 insertions, 22 deletions
diff --git a/avmedia/source/framework/mediaitem.cxx b/avmedia/source/framework/mediaitem.cxx
index 77b28918f545..f177c8bea687 100644
--- a/avmedia/source/framework/mediaitem.cxx
+++ b/avmedia/source/framework/mediaitem.cxx
@@ -36,6 +36,7 @@
#include <ucbhelper/content.hxx>
+#include <comphelper/mediamimetype.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/storagehelper.hxx>
#include <mediamisc.hxx>
@@ -237,6 +238,7 @@ bool MediaItem::setURL(const OUString& rURL, const OUString& rTempURL, const OUS
m_pImpl->m_URL = rURL;
m_pImpl->m_TempFileURL = rTempURL;
m_pImpl->m_Referer = rReferer;
+ setMimeType(::comphelper::GuessMediaMimeType(GetFilename(rURL)));
}
return bChanged;
}
@@ -447,10 +449,9 @@ CreateStream(uno::Reference<embed::XStorage> const& xStorage,
uno::Reference< beans::XPropertySet > const xStreamProps(xStream,
uno::UNO_QUERY);
if (xStreamProps.is()) { // this is NOT supported in FileSystemStorage
- xStreamProps->setPropertyValue("MediaType", uno::Any(OUString(
- //FIXME how to detect real media type?
- //but currently xmloff has this one hardcoded anyway...
- "application/vnd.sun.star.media")));
+ OUString const guessed(::comphelper::GuessMediaMimeType(filename));
+ xStreamProps->setPropertyValue("MediaType",
+ uno::Any(guessed.isEmpty() ? AVMEDIA_MIMETYPE_COMMON : guessed));
xStreamProps->setPropertyValue( // turn off compression
"Compressed", uno::Any(false));
}
diff --git a/avmedia/source/inc/mediamisc.hxx b/avmedia/source/inc/mediamisc.hxx
index 061a7177f05a..f45f5b50da0b 100644
--- a/avmedia/source/inc/mediamisc.hxx
+++ b/avmedia/source/inc/mediamisc.hxx
@@ -19,6 +19,8 @@
#pragma once
+#include <comphelper/mediamimetype.hxx>
+
#include <unotools/resmgr.hxx>
#ifdef _WIN32
@@ -31,9 +33,6 @@
#endif
#endif
-// Mime types
-inline constexpr OUStringLiteral AVMEDIA_MIMETYPE_COMMON = u"application/vnd.sun.star.media";
-
inline OUString AvmResId(TranslateId aId)
{
return Translate::get(aId, Translate::Create("avmedia"));
diff --git a/avmedia/source/viewer/mediawindow_impl.cxx b/avmedia/source/viewer/mediawindow_impl.cxx
index b74033e33749..82ca1b92821c 100644
--- a/avmedia/source/viewer/mediawindow_impl.cxx
+++ b/avmedia/source/viewer/mediawindow_impl.cxx
@@ -168,7 +168,7 @@ void MediaWindowImpl::dispose()
Control::dispose();
}
-uno::Reference<media::XPlayer> MediaWindowImpl::createPlayer(const OUString& rURL, const OUString& rReferer, const OUString* pMimeType)
+uno::Reference<media::XPlayer> MediaWindowImpl::createPlayer(const OUString& rURL, const OUString& rReferer, const OUString*)
{
uno::Reference<media::XPlayer> xPlayer;
@@ -180,7 +180,8 @@ uno::Reference<media::XPlayer> MediaWindowImpl::createPlayer(const OUString& rUR
return xPlayer;
}
- if (!pMimeType || *pMimeType == AVMEDIA_MIMETYPE_COMMON)
+ // currently there isn't anything else, throw any mime type to the media players
+ //if (!pMimeType || *pMimeType == AVMEDIA_MIMETYPE_COMMON)
{
uno::Reference<uno::XComponentContext> xContext(::comphelper::getProcessComponentContext());
if (Application::GetToolkitName() == "gtk4")
@@ -397,7 +398,7 @@ void MediaWindowImpl::stopPlayingInternal(bool bStop)
void MediaWindowImpl::onURLChanged()
{
- if (m_sMimeType == AVMEDIA_MIMETYPE_COMMON)
+ //if (m_sMimeType == AVMEDIA_MIMETYPE_COMMON)
{
mpChildWindow.disposeAndClear();
mpChildWindow.reset(VclPtr<MediaChildWindow>::Create(this));
diff --git a/comphelper/source/misc/graphicmimetype.cxx b/comphelper/source/misc/graphicmimetype.cxx
index f9c6034ac8f9..8ae3dad5619c 100644
--- a/comphelper/source/misc/graphicmimetype.cxx
+++ b/comphelper/source/misc/graphicmimetype.cxx
@@ -18,6 +18,10 @@
*/
#include <comphelper/graphicmimetype.hxx>
+#include <comphelper/mediamimetype.hxx>
+
+#include <map>
+#include <set>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
@@ -166,6 +170,70 @@ char const* GraphicMimeTypeHelper::GetExtensionForConvertDataFormat(ConvertDataF
}
return pExt;
}
+
+static auto GetMediaMimes() -> std::map<OString, OString> const&
+{
+ static std::map<OString, OString> const mimes = {
+ { "mp4", "video/mp4" },
+ { "ts", "video/MP2T" },
+ { "mpeg", "video/mpeg" },
+ { "mpg", "video/mpeg" },
+ { "mkv", "video/x-matroska" },
+ { "webm", "video/webm" },
+ { "ogv", "video/ogg" },
+ { "mov", "video/quicktime" },
+ { "wmv", "video/x-ms-wmv" },
+ { "avi", "video/x-msvideo" },
+ { "m4a", "audio/mp4" },
+ { "aac", "audio/aac" },
+ { "mp3", "audio/mpeg" }, // https://bugs.chromium.org/p/chromium/issues/detail?id=227004
+ { "ogg", "audio/ogg" },
+ { "oga", "audio/ogg" },
+ { "opus", "audio/ogg" },
+ { "flac", "audio/flac" }, // missing at IANA?
+ // note there is RFC 2631 but i got the impression that vnd.wave
+ // requires specifying the codec in the container; also this page
+ // says "Historic" whatever that means:
+ // https://www.iana.org/assignments/wave-avi-codec-registry/wave-avi-codec-registry.xhtml
+ { "wav", "audio/x-wav" },
+ };
+ return mimes;
+}
+
+auto IsMediaMimeType(::std::string_view const rMimeType) -> bool
+{
+ return IsMediaMimeType(OStringToOUString(rMimeType, RTL_TEXTENCODING_UTF8));
+}
+
+auto IsMediaMimeType(OUString const& rMimeType) -> bool
+{
+ static std::set<OUString> mimes;
+ if (mimes.empty())
+ {
+ auto const& rMap(GetMediaMimes());
+ for (auto const& it : rMap)
+ {
+ mimes.insert(OStringToOUString(it.second, RTL_TEXTENCODING_UTF8));
+ }
+ }
+ return rMimeType == AVMEDIA_MIMETYPE_COMMON || mimes.find(rMimeType) != mimes.end();
+}
+
+auto GuessMediaMimeType(::std::u16string_view rFileName) -> OUString
+{
+ if (auto const i = rFileName.rfind('.'); i != ::std::string_view::npos)
+ {
+ OString const ext(OUStringToOString(rFileName.substr(i + 1), RTL_TEXTENCODING_UTF8));
+ auto const& rMap(GetMediaMimes());
+ auto const it(rMap.find(ext));
+ if (it != rMap.end())
+ {
+ return OStringToOUString(it->second, RTL_TEXTENCODING_ASCII_US);
+ }
+ }
+ return OUString();
}
+} // namespace comphelper
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/comphelper/mediamimetype.hxx b/include/comphelper/mediamimetype.hxx
new file mode 100644
index 000000000000..21b7ffa9211b
--- /dev/null
+++ b/include/comphelper/mediamimetype.hxx
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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/.
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <rtl/ustring.hxx>
+
+#include <comphelper/comphelperdllapi.h>
+
+inline constexpr OUStringLiteral AVMEDIA_MIMETYPE_COMMON = u"application/vnd.sun.star.media";
+
+namespace comphelper
+{
+COMPHELPER_DLLPUBLIC auto IsMediaMimeType(::std::string_view const rMimeType) -> bool;
+COMPHELPER_DLLPUBLIC auto IsMediaMimeType(OUString const& rMimeType) -> bool;
+COMPHELPER_DLLPUBLIC auto GuessMediaMimeType(::std::u16string_view rFileName) -> OUString;
+
+} // namespace comphelper
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/include/svx/svdomedia.hxx b/include/svx/svdomedia.hxx
index 6f08611a7002..e3120c672f3d 100644
--- a/include/svx/svdomedia.hxx
+++ b/include/svx/svdomedia.hxx
@@ -58,7 +58,7 @@ public:
virtual void AdjustToMaxRect( const tools::Rectangle& rMaxRect, bool bShrinkOnly = false ) override;
- void setURL( const OUString& rURL, const OUString& rReferer, const OUString& rMimeType = OUString() );
+ void setURL(const OUString& rURL, const OUString& rReferer);
const OUString& getURL() const;
/// Returns the URL to the temporary extracted media file.
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index d610435d0eb2..59d67393bed5 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -1425,6 +1425,11 @@ void DrawingML::WriteMediaNonVisualProperties(const css::uno::Reference<css::dra
#else
OUString aMimeType("none");
#endif
+ if (aMimeType.startsWith("audio/"))
+ {
+ eMediaType = Relationship::AUDIO;
+ }
+ else
if (aMimeType == "application/vnd.sun.star.media")
{
// try to set something better
diff --git a/sd/source/ui/inc/View.hxx b/sd/source/ui/inc/View.hxx
index 4e530e3f9227..342bf7b6256a 100644
--- a/sd/source/ui/inc/View.hxx
+++ b/sd/source/ui/inc/View.hxx
@@ -172,7 +172,7 @@ public:
void InsertMediaURL( const OUString& rMediaURL, sal_Int8& rAction,
const Point& rPos, const Size& rSize,
bool const bLink );
- SdrMediaObj* InsertMediaObj( const OUString& rURL, const OUString& rMimeType, sal_Int8& rAction,
+ SdrMediaObj* InsertMediaObj(const OUString& rURL, sal_Int8& rAction,
const Point& rPos, const Size& rSize );
bool PasteRTFTable( const ::tools::SvRef<SotTempStream>& xStm, SdrPage* pPage, SdrInsertFlags nPasteOptions );
diff --git a/sd/source/ui/view/sdview4.cxx b/sd/source/ui/view/sdview4.cxx
index e91ee2c691c1..f46c876dac2b 100644
--- a/sd/source/ui/view/sdview4.cxx
+++ b/sd/source/ui/view/sdview4.cxx
@@ -319,10 +319,10 @@ void View::InsertMediaURL( const OUString& rMediaURL, sal_Int8& rAction,
#endif
}
- InsertMediaObj( realURL, "application/vnd.sun.star.media", rAction, rPos, rSize );
+ InsertMediaObj(realURL, rAction, rPos, rSize);
}
-SdrMediaObj* View::InsertMediaObj( const OUString& rMediaURL, const OUString& rMimeType, sal_Int8& rAction,
+SdrMediaObj* View::InsertMediaObj( const OUString& rMediaURL, sal_Int8& rAction,
const Point& rPos, const Size& rSize )
{
SdrEndTextEdit();
@@ -341,7 +341,7 @@ SdrMediaObj* View::InsertMediaObj( const OUString& rMediaURL, const OUString& rM
if( mnAction == DND_ACTION_LINK && pPV && dynamic_cast< SdrMediaObj *>( pPickObj ) )
{
pNewMediaObj = SdrObject::Clone(static_cast<SdrMediaObj&>(*pPickObj), pPickObj->getSdrModelFromSdrObject());
- pNewMediaObj->setURL( rMediaURL, ""/*TODO?*/, rMimeType );
+ pNewMediaObj->setURL(rMediaURL, ""/*TODO?*/);
BegUndo(SdResId(STR_UNDO_DRAGDROP));
ReplaceObjectAtView(pPickObj, *pPV, pNewMediaObj.get());
@@ -388,7 +388,7 @@ SdrMediaObj* View::InsertMediaObj( const OUString& rMediaURL, const OUString& rM
if (pNewMediaObj)
{
- pNewMediaObj->setURL( rMediaURL, referer, rMimeType );
+ pNewMediaObj->setURL(rMediaURL, referer);
if( pPickObj )
{
diff --git a/svx/source/svdraw/svdomedia.cxx b/svx/source/svdraw/svdomedia.cxx
index 17785a5d693a..73b19ca78773 100644
--- a/svx/source/svdraw/svdomedia.cxx
+++ b/svx/source/svdraw/svdomedia.cxx
@@ -252,12 +252,10 @@ void SdrMediaObj::AdjustToMaxRect( const tools::Rectangle& rMaxRect, bool bShrin
SetLogicRect( tools::Rectangle( aPos, aSize ) );
}
-void SdrMediaObj::setURL( const OUString& rURL, const OUString& rReferer, const OUString& rMimeType )
+void SdrMediaObj::setURL(const OUString& rURL, const OUString& rReferer)
{
::avmedia::MediaItem aURLItem;
#if HAVE_FEATURE_AVMEDIA
- if( !rMimeType.isEmpty() )
- m_xImpl->m_MediaProperties.setMimeType(rMimeType);
aURLItem.setURL( rURL, "", rReferer );
#else
(void) rMimeType;
diff --git a/xmloff/source/draw/ximpshap.cxx b/xmloff/source/draw/ximpshap.cxx
index 22f9d7ddb0a1..0e7ce7a1619f 100644
--- a/xmloff/source/draw/ximpshap.cxx
+++ b/xmloff/source/draw/ximpshap.cxx
@@ -61,6 +61,7 @@
#include <sax/tools/converter.hxx>
#include <comphelper/sequence.hxx>
#include <comphelper/diagnose_ex.hxx>
+#include <comphelper/mediamimetype.hxx>
#include <xmloff/families.hxx>
#include<xmloff/xmlnamespace.hxx>
@@ -2890,7 +2891,7 @@ void SdXMLPluginShapeContext::startFastElement (sal_Int32 /*nElement*/,
{
if( aIter.getToken() == XML_ELEMENT(DRAW, XML_MIME_TYPE) )
{
- if( aIter.toView() == "application/vnd.sun.star.media" )
+ if (::comphelper::IsMediaMimeType(aIter.toView()))
mbMedia = true;
// leave this loop
break;
@@ -3335,7 +3336,7 @@ css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLFrameShapeContext
mxImplContext = nullptr;
return new SvXMLImportContext(GetImport());
}
- else if (pPluginContext && pPluginContext->getMimeType() == "application/vnd.sun.star.media")
+ else if (pPluginContext && ::comphelper::IsMediaMimeType(pPluginContext->getMimeType()))
{
// The media may have a preview, import it.
bMedia = true;
diff --git a/xmloff/source/text/XMLTextFrameContext.cxx b/xmloff/source/text/XMLTextFrameContext.cxx
index bd145b5213cd..8d0bac4964dc 100644
--- a/xmloff/source/text/XMLTextFrameContext.cxx
+++ b/xmloff/source/text/XMLTextFrameContext.cxx
@@ -22,6 +22,7 @@
#include <sal/log.hxx>
#include <comphelper/diagnose_ex.hxx>
#include <comphelper/base64.hxx>
+#include <comphelper/mediamimetype.hxx>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/text/TextContentAnchorType.hpp>
@@ -1493,7 +1494,7 @@ css::uno::Reference< css::xml::sax::XFastContextHandler > XMLTextFrameContext::c
{
if( aIter.getToken() == XML_ELEMENT(DRAW, XML_MIME_TYPE) )
{
- if( aIter.toView() == "application/vnd.sun.star.media" )
+ if (::comphelper::IsMediaMimeType(aIter.toView()))
bMedia = true;
// leave this loop