// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. #include "FFMPEGMediaFactoryPrivate.h" #include "Containers/Array.h" #include "Containers/UnrealString.h" #include "IMediaModule.h" #include "IMediaOptions.h" #include "IMediaPlayerFactory.h" #include "Internationalization/Internationalization.h" #include "Misc/Paths.h" #include "Modules/ModuleInterface.h" #include "Modules/ModuleManager.h" #include "UObject/NameTypes.h" #if PLATFORM_WINDOWS #include "Windows/WindowsHWrapper.h" #endif #if WITH_EDITOR #include "ISettingsModule.h" #include "Templates/SharedPointer.h" #include "UObject/Class.h" #include "UObject/WeakObjectPtr.h" #include "FFMPEGMediaSettings.h" #endif #include "../../FFMPEGMedia/Public/IFFMPEGMediaModule.h" DEFINE_LOG_CATEGORY(LogFFMPEGMediaFactory); #define LOCTEXT_NAMESPACE "FMPEGMediaFactoryModule" /** * Implements the WmfMediaFactory module. */ class FFFMPEGMediaFactoryModule : public IMediaPlayerFactory , public IModuleInterface { public: /** Default constructor. */ FFFMPEGMediaFactoryModule() { } public: //~ IMediaPlayerFactory interface virtual bool CanPlayUrl(const FString& Url, const IMediaOptions* Options, TArray* OutWarnings, TArray* OutErrors) const override { FString Scheme; FString Location; // check scheme if (!Url.Split(TEXT("://"), &Scheme, &Location, ESearchCase::CaseSensitive)) { if (OutErrors != nullptr) { OutErrors->Add(LOCTEXT("NoSchemeFound", "No URI scheme found")); } return false; } if (!SupportedUriSchemes.Contains(Scheme)) { if (OutErrors != nullptr) { OutErrors->Add(FText::Format(LOCTEXT("SchemeNotSupported", "The URI scheme '{0}' is not supported"), FText::FromString(Scheme))); } return false; } // check file extension if (Scheme == TEXT("file")) { const FString Extension = FPaths::GetExtension(Location, false); if (!SupportedFileExtensions.Contains(Extension)) { if (OutErrors != nullptr) { OutErrors->Add(FText::Format(LOCTEXT("ExtensionNotSupported", "The file extension '{0}' is not supported"), FText::FromString(Extension))); } return false; } } // check options if ((OutWarnings != nullptr) && (Options != nullptr)) { if (Options->GetMediaOption("PrecacheFile", false) && (Scheme != TEXT("file"))) { OutWarnings->Add(LOCTEXT("PrecachingNotSupported", "Precaching is supported for local files only")); } } return true; } virtual FGuid GetPlayerPluginGUID() const override { // {938BEEB4-2E88-450E-9C1C-6109456279B3} static FGuid PlayerPluginGUID(0x938beeb4, 0x2e88450e, 0x9c1c6109, 0x456279b3); return PlayerPluginGUID; } virtual TSharedPtr CreatePlayer(IMediaEventSink& EventSink) override { auto FFMPEGMediaModule = FModuleManager::LoadModulePtr("FFMPEGMedia"); return (FFMPEGMediaModule != nullptr) ? FFMPEGMediaModule->CreatePlayer(EventSink) : nullptr; } virtual FText GetDisplayName() const override { return LOCTEXT("MediaPlayerDisplayName", "FFMPEG"); } virtual FName GetPlayerName() const override { static FName PlayerName(TEXT("FFMPEGMedia")); return PlayerName; } virtual const TArray& GetSupportedPlatforms() const override { return SupportedPlatforms; } virtual bool SupportsFeature(EMediaFeature Feature) const override { return ((Feature == EMediaFeature::AudioSamples) || (Feature == EMediaFeature::AudioTracks) || (Feature == EMediaFeature::CaptionTracks) || (Feature == EMediaFeature::MetadataTracks) || (Feature == EMediaFeature::OverlaySamples) || (Feature == EMediaFeature::SubtitleTracks) || (Feature == EMediaFeature::VideoSamples) || (Feature == EMediaFeature::VideoTracks)); } public: //~ IModuleInterface interface virtual void StartupModule() override { auto FFMPEGMediaModule = FModuleManager::LoadModulePtr("FFMPEGMedia"); SupportedFileExtensions.Append(FFMPEGMediaModule->GetSupportedFileExtensions()); SupportedUriSchemes.Append(FFMPEGMediaModule->GetSupportedUriSchemes() ); // supported platforms SupportedPlatforms.Add(TEXT("Windows")); SupportedPlatforms.Add(TEXT("Mac")); SupportedPlatforms.Add(TEXT("Android")); #if WITH_EDITOR // register settings ISettingsModule* SettingsModule = FModuleManager::GetModulePtr("Settings"); if (SettingsModule != nullptr) { SettingsModule->RegisterSettings("Project", "Plugins", "FFMPEGMedia", LOCTEXT("FFMPEGMediaSettingsName", "FFMPEG Media"), LOCTEXT("FFMPEGMediaSettingsDescription", "Configure the FFMPEG Media plug-in."), GetMutableDefault() ); } #endif //WITH_EDITOR // register player factory auto MediaModule = FModuleManager::LoadModulePtr("Media"); if (MediaModule != nullptr) { MediaModule->RegisterPlayerFactory(*this); } } virtual void ShutdownModule() override { // unregister player factory auto MediaModule = FModuleManager::GetModulePtr("Media"); if (MediaModule != nullptr) { MediaModule->UnregisterPlayerFactory(*this); } #if WITH_EDITOR // unregister settings ISettingsModule* SettingsModule = FModuleManager::GetModulePtr("Settings"); if (SettingsModule != nullptr) { SettingsModule->UnregisterSettings("Project", "Plugins", "FFMPEGMedia"); } #endif //WITH_EDITOR } private: /** List of supported media file types. */ TArray SupportedFileExtensions; /** List of platforms that the media player support. */ TArray SupportedPlatforms; /** List of supported URI schemes. */ TArray SupportedUriSchemes; }; #undef LOCTEXT_NAMESPACE IMPLEMENT_MODULE(FFFMPEGMediaFactoryModule, FFMPEGMediaFactory);