avmedia/source/framework/mediaitem.cxx     |    9 ++-
 avmedia/source/inc/mediamisc.hxx           |    5 --
 avmedia/source/viewer/mediawindow_impl.cxx |    7 +-
 comphelper/source/misc/graphicmimetype.cxx |   68 +++++++++++++++++++++++++++++
 include/comphelper/mediamimetype.hxx       |   30 ++++++++++++
 include/svx/svdomedia.hxx                  |    2 
 oox/source/export/drawingml.cxx            |    5 ++
 sd/source/ui/inc/View.hxx                  |    2 
 sd/source/ui/view/sdview4.cxx              |    8 +--
 svx/source/svdraw/svdomedia.cxx            |    4 -
 xmloff/source/draw/ximpshap.cxx            |    5 +-
 xmloff/source/text/XMLTextFrameContext.cxx |    3 -
 12 files changed, 126 insertions(+), 22 deletions(-)

New commits:
commit a5225ba82e94a549f44420f56a7cb9d7906561cc
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Wed Apr 5 11:50:44 2023 +0200
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Wed Apr 5 14:34:51 2023 +0200

    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.st...@allotropia.de>

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

Reply via email to