From f499e076337f205eeec9b4e7f8287d3f10d3d834 Mon Sep 17 00:00:00 2001 From: agsantos <aline.gondimsantos@savoirfairelinux.com> Date: Thu, 26 Nov 2020 16:30:57 -0500 Subject: [PATCH] SDK: add audio option for MediaHandler API - modify AudioFilter for Windows build Change-Id: Icddd014b0d42cd3848000c7b8b97baa7cab709aa GitLab: #3 --- AudioFilter/CMakeLists.txt | 2 +- AudioFilter/filterAudioSubscriber.cpp | 1 - SDK/Docs/functionalityHelper.txt | 1 + SDK/Templates/CMakeLists.txt | 11 +- SDK/Templates/audioUpdate.txt | 18 +++ SDK/Templates/build.sh | 12 +- SDK/Templates/defaultDependenciesStrings.json | 10 -- SDK/Templates/defaultStrings.json | 38 ++++++ SDK/Templates/genericMediaHandler.cpp | 13 +- SDK/Templates/genericMediaHandler.h | 4 +- SDK/Templates/genericMediaSubscriber.cpp | 66 ++++++++++ ...oSubscriber.h => genericMediaSubscriber.h} | 15 +-- SDK/Templates/videoUpdate.txt | 53 ++++++++ SDK/sdkConstants.py | 8 +- SDK/skeletonSrcProfile.py | 113 +++++++++++++++--- 15 files changed, 305 insertions(+), 60 deletions(-) create mode 100644 SDK/Templates/audioUpdate.txt delete mode 100644 SDK/Templates/defaultDependenciesStrings.json create mode 100644 SDK/Templates/defaultStrings.json create mode 100644 SDK/Templates/genericMediaSubscriber.cpp rename SDK/Templates/{genericVideoSubscriber.h => genericMediaSubscriber.h} (69%) create mode 100644 SDK/Templates/videoUpdate.txt diff --git a/AudioFilter/CMakeLists.txt b/AudioFilter/CMakeLists.txt index 25d6172..0044e42 100644 --- a/AudioFilter/CMakeLists.txt +++ b/AudioFilter/CMakeLists.txt @@ -68,7 +68,7 @@ target_link_directories(${ProjectName} PUBLIC ${CONTRIB_PATH} ${FFMPEG}/bin ) -target_link_libraries(${ProjectName} PUBLIC avformat swscale swresample avcodec avfilter avutil vpx x264) +target_link_libraries(${ProjectName} PUBLIC avformat swscale swresample avcodec avfilter avutil) add_custom_command( TARGET ${ProjectName} diff --git a/AudioFilter/filterAudioSubscriber.cpp b/AudioFilter/filterAudioSubscriber.cpp index ad9d779..13e7fee 100644 --- a/AudioFilter/filterAudioSubscriber.cpp +++ b/AudioFilter/filterAudioSubscriber.cpp @@ -21,7 +21,6 @@ #include "filterAudioSubscriber.h" extern "C" { -#include <libavutil/display.h> #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libavfilter/buffersrc.h> diff --git a/SDK/Docs/functionalityHelper.txt b/SDK/Docs/functionalityHelper.txt index b238fdc..f36ac3d 100644 --- a/SDK/Docs/functionalityHelper.txt +++ b/SDK/Docs/functionalityHelper.txt @@ -7,6 +7,7 @@ multiple functionalities. Each functionality may be applied to different data types that requires diferent APIs. Currently, our plugin system supports the following data: (1) video during a call (Media Handler API). +(2) audio during a call (Media Handler API). Be aware that when creating functionalities outside a full plugin pipeline diff --git a/SDK/Templates/CMakeLists.txt b/SDK/Templates/CMakeLists.txt index 73df875..a855ea4 100644 --- a/SDK/Templates/CMakeLists.txt +++ b/SDK/Templates/CMakeLists.txt @@ -38,15 +38,12 @@ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") set(plugin_SRC ---CPPFILENAME - ---../lib/accel.cppFFMPEGCPP - ../lib/frameUtils.cpp + ---FFMPEGCPP ---) set(plugin_HDR ---HFILENAME - ---../lib/accel.hFFMPEGH - ../lib/frameScaler.h - ../lib/frameUtils.h - ---../lib/pluglog.h + ---FFMPEGH + ---./../lib/pluglog.h ) add_library(${ProjectName} SHARED ${plugin_SRC} @@ -64,7 +61,7 @@ target_link_directories(${ProjectName} PUBLIC ${CONTRIB_PATH} ---${FFMPEG}/bin--- ) -target_link_libraries(${ProjectName} PUBLIC ---swscale avutil---) +target_link_libraries(${ProjectName} PUBLIC ---FFMPEGLIBS---) add_custom_command( TARGET ${ProjectName} diff --git a/SDK/Templates/audioUpdate.txt b/SDK/Templates/audioUpdate.txt new file mode 100644 index 0000000..3d8adf2 --- /dev/null +++ b/SDK/Templates/audioUpdate.txt @@ -0,0 +1,18 @@ + if (!pluginFrame) + return; + + if (firstRun) { + // IMPLEMENT CODE TO CONFIGURE + // VARIABLES UPON FIRST RUN + firstRun = false; + } + + AVFrame* processedFrame = nullptr; + + // IMPLEMENT PROCESS + + if (processedFrame) { + moveFrom(pluginFrame, processedFrame); + av_frame_unref(processedFrame); + av_frame_free(&processedFrame); + } \ No newline at end of file diff --git a/SDK/Templates/build.sh b/SDK/Templates/build.sh index 16e4809..c6ebb73 100644 --- a/SDK/Templates/build.sh +++ b/SDK/Templates/build.sh @@ -63,12 +63,11 @@ then -I"${DAEMON_SRC}" \ -I"${CONTRIB_PATH}/${CONTRIB_PLATFORM}/include" \ -I"${PLUGINS_LIB}" \ - ---FFMPEGCPP./../lib/accel.cpp \ + ---FFMPEGCPP \ ---CPPFILENAME \ ----L"${CONTRIB_PATH}/${CONTRIB_PLATFORM}/lib/" \ - ----l:libswscale.a \ - -l:libavutil.a \ - -lva \ + ----FFMPEGLIBS \ + ---FFMPEGEXTRA-lva \ ----o "build-local/jpl/lib/${CONTRIB_PLATFORM_CURT}-linux-gnu/${SO_FILE_NAME}" elif [ "${PLATFORM}" = "android" ] @@ -185,11 +184,10 @@ then -I"${DAEMON_SRC}" \ -I"${CONTRIB_PATH}/${CONTRIB_PLATFORM}/include" \ -I"${PLUGINS_LIB}" \ - ---FFMPEGCPP./../lib/accel.cpp \ + ---FFMPEGCPP \ ---CPPFILENAME \ ----L"${CONTRIB_PATH}/${CONTRIB_PLATFORM}/lib/" \ - ----lswscale \ - -lavutil \ + ----FFMPEGLIBS \ ----llog -lz \ --sysroot=$ANDROID_SYSROOT \ -o "build-local/jpl/lib/$CURRENT_ABI/${SO_FILE_NAME}" diff --git a/SDK/Templates/defaultDependenciesStrings.json b/SDK/Templates/defaultDependenciesStrings.json deleted file mode 100644 index 3488cb8..0000000 --- a/SDK/Templates/defaultDependenciesStrings.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "package.json": - { - "MediaHandler": { - "deps": [ - "ffmpeg" - ] - } - } -} \ No newline at end of file diff --git a/SDK/Templates/defaultStrings.json b/SDK/Templates/defaultStrings.json new file mode 100644 index 0000000..e3cb305 --- /dev/null +++ b/SDK/Templates/defaultStrings.json @@ -0,0 +1,38 @@ +{ + "package.json": + { + "MediaHandler": { + "deps": [ + "ffmpeg" + ] + } + }, + "genericmediasubscriber": + { + "header": { + "VideoINCLUDES": ["#include <frameScaler.h>"], + "VideoPRIVATE": ["FrameScaler scaler;"], + "AudioINCLUDES": [], + "AudioPRIVATE": [] + }, + "impl": { + "FFMPEGVideoINCLUDES": ["#include <libavutil/display.h>"], + "VideoINCLUDES": ["#include <accel.h>"], + "VideoUPDATE": "videoUpdate.txt", + "FFMPEGAudioINCLUDES": [], + "AudioINCLUDES": [], + "AudioUPDATE": "audioUpdate.txt" + } + }, + "buildFiles": + { + "MediaHandler": { + "VideoFFMPEGCPP": ["./../lib/accel.cpp", "./../lib/frameUtils.cpp"], + "VideoFFMPEGH": ["./../lib/accel.h", "./../lib/frameScaler.h", "./../lib/frameUtils.h"], + "VideoFFMPEGLIBS": ["swscale", "avutil"], + "AudioFFMPEGCPP": ["./../lib/frameUtils.cpp"], + "AudioFFMPEGH": ["./../lib/frameUtils.h"], + "AudioFFMPEGLIBS": ["avutil"] + } + } +} \ No newline at end of file diff --git a/SDK/Templates/genericMediaHandler.cpp b/SDK/Templates/genericMediaHandler.cpp index a55a964..3254925 100644 --- a/SDK/Templates/genericMediaHandler.cpp +++ b/SDK/Templates/genericMediaHandler.cpp @@ -17,27 +17,26 @@ GENERICMediaHandler::GENERICMediaHandler(std::map<std::string, std::string>&& pp , ppm_ {ppm} { setId(datapath_); - mVS = std::make_shared<GENERICVideoSubscriber>(datapath_); + mediaSubscriber_ = std::make_shared<GENERICDATATYPESubscriber>(datapath_); } void GENERICMediaHandler::notifyAVFrameSubject(const StreamData& data, jami::avSubjectPtr subject) { - Plog::log(Plog::LogPriority::INFO, TAG, "IN AVFRAMESUBJECT"); std::ostringstream oss; std::string direction = data.direction ? "Receive" : "Preview"; oss << "NEW SUBJECT: [" << data.id << "," << direction << "]" << std::endl; bool preferredStreamDirection = false; // false for output; true for input oss << "preferredStreamDirection " << preferredStreamDirection << std::endl; - if (data.type == StreamType::video && !data.direction + if (data.type == StreamType::DataType && !data.direction && data.direction == preferredStreamDirection) { - subject->attach(mVS.get()); // your image + subject->attach(mediaSubscriber_.get()); // your image oss << "got my sent image attached" << std::endl; attached_ = "1"; - } else if (data.type == StreamType::video && data.direction + } else if (data.type == StreamType::DataType && data.direction && data.direction == preferredStreamDirection) { - subject->attach(mVS.get()); // the image you receive from others on the call + subject->attach(mediaSubscriber_.get()); // the image you receive from others on the call oss << "got received image attached" << std::endl; attached_ = "1"; } @@ -79,7 +78,7 @@ void GENERICMediaHandler::detach() { attached_ = "0"; - mVS->detach(); + mediaSubscriber_->detach(); } GENERICMediaHandler::~GENERICMediaHandler() diff --git a/SDK/Templates/genericMediaHandler.h b/SDK/Templates/genericMediaHandler.h index 440c9e2..51c8c9b 100644 --- a/SDK/Templates/genericMediaHandler.h +++ b/SDK/Templates/genericMediaHandler.h @@ -2,7 +2,7 @@ HEADER #pragma once -#include "GENERICVideoSubscriber.h" +#include "GENERICDATATYPESubscriber.h" #include "plugin/jamiplugin.h" #include "plugin/mediahandler.h" @@ -24,7 +24,7 @@ public: virtual void setPreferenceAttribute(const std::string& key, const std::string& value) override; virtual bool preferenceMapHasKey(const std::string& key) override; - std::shared_ptr<GENERICVideoSubscriber> mVS; + std::shared_ptr<GENERICDATATYPESubscriber> mediaSubscriber_; const std::string& dataPath() const { return datapath_; } diff --git a/SDK/Templates/genericMediaSubscriber.cpp b/SDK/Templates/genericMediaSubscriber.cpp new file mode 100644 index 0000000..b90df41 --- /dev/null +++ b/SDK/Templates/genericMediaSubscriber.cpp @@ -0,0 +1,66 @@ +HEADER + +#include "GENERICDATATYPESubscriber.h" + +--- +extern "C" { +FFMPEGDATATYPEINCLUDES +}--- +---DATATYPEINCLUDES +--- +#include <pluglog.h> +#include <frameUtils.h> + +const std::string TAG = "GENERIC"; +const char sep = separator(); + +namespace jami { + +GENERICDATATYPESubscriber::GENERICDATATYPESubscriber(const std::string& dataPath) + : path_ {dataPath} +{} + +GENERICDATATYPESubscriber::~GENERICDATATYPESubscriber() +{ + std::ostringstream oss; + oss << "~GENERICMediaProcessor" << std::endl; + Plog::log(Plog::LogPriority::INFO, TAG, oss.str()); +} + +void +GENERICDATATYPESubscriber::update(jami::Observable<AVFrame*>*, AVFrame* const& pluginFrame) +{ +---DATATYPEUPDATE--- +} + +void +GENERICDATATYPESubscriber::attached(jami::Observable<AVFrame*>* observable) +{ + std::ostringstream oss; + oss << "::Attached ! " << std::endl; + Plog::log(Plog::LogPriority::INFO, TAG, oss.str()); + observable_ = observable; +} + +void +GENERICDATATYPESubscriber::detached(jami::Observable<AVFrame*>*) +{ + firstRun = true; + observable_ = nullptr; + std::ostringstream oss; + oss << "::Detached()" << std::endl; + Plog::log(Plog::LogPriority::INFO, TAG, oss.str()); +} + +void +GENERICDATATYPESubscriber::detach() +{ + if (observable_) { + firstRun = true; + std::ostringstream oss; + oss << "::Calling detach()" << std::endl; + Plog::log(Plog::LogPriority::INFO, TAG, oss.str()); + observable_->detach(this); + } +} +} // namespace jami diff --git a/SDK/Templates/genericVideoSubscriber.h b/SDK/Templates/genericMediaSubscriber.h similarity index 69% rename from SDK/Templates/genericVideoSubscriber.h rename to SDK/Templates/genericMediaSubscriber.h index e3db081..412d6f1 100644 --- a/SDK/Templates/genericVideoSubscriber.h +++ b/SDK/Templates/genericMediaSubscriber.h @@ -6,15 +6,16 @@ extern "C" { #include <libavutil/frame.h> } #include <observer.h> -#include <frameScaler.h> +---DATATYPEINCLUDES +--- namespace jami { -class GENERICVideoSubscriber : public jami::Observer<AVFrame*> +class GENERICDATATYPESubscriber : public jami::Observer<AVFrame*> { public: - GENERICVideoSubscriber(const std::string& dataPath); - ~GENERICVideoSubscriber(); + GENERICDATATYPESubscriber(const std::string& dataPath); + ~GENERICDATATYPESubscriber(); virtual void update(jami::Observable<AVFrame*>*, AVFrame* const&) override; virtual void attached(jami::Observable<AVFrame*>*) override; @@ -27,9 +28,9 @@ private: Observable<AVFrame*>* observable_ = nullptr; // Data - std::string path_; - FrameScaler scaler; - + std::string path_;--- + DATATYPEPRIVATE +--- // Status variables of the processing bool firstRun {true}; }; diff --git a/SDK/Templates/videoUpdate.txt b/SDK/Templates/videoUpdate.txt new file mode 100644 index 0000000..b72d443 --- /dev/null +++ b/SDK/Templates/videoUpdate.txt @@ -0,0 +1,53 @@ + if (!pluginFrame) + return; + + //====================================================================================== + // GET FRAME ROTATION + AVFrameSideData* side_data = av_frame_get_side_data(pluginFrame, AV_FRAME_DATA_DISPLAYMATRIX); + + int angle {0}; + if (side_data) { + auto matrix_rotation = reinterpret_cast<int32_t*>(side_data->data); + angle = static_cast<int>(av_display_rotation_get(matrix_rotation)); + } + delete side_data; + + //====================================================================================== + // GET RAW FRAME + // Use a non-const Frame + // Convert input frame to RGB + AVFrame* temp = transferToMainMemory(pluginFrame, AV_PIX_FMT_NV12); + AVFrame* bgrFrame = scaler.convertFormat(temp, AV_PIX_FMT_RGB24); + av_frame_unref(temp); + av_frame_free(&temp); + if (!bgrFrame) + return; + + // transferToMainMemory USED TO COPY FRAME TO MAIN MEMORY IF HW ACCEL IS ENABLED + // NOT NEEDED TO BE USED IF ALL YOUR PROCESS WILL BE DONE WITHIN A + // HW ACCEL PLATFORM + + if (firstRun) { + // IMPLEMENT CODE TO CONFIGURE + // VARIABLES UPON FIRST RUN + firstRun = false; + } + + // IMPLEMENT PROCESS + + //====================================================================================== + // REPLACE AVFRAME DATA WITH FRAME DATA + if (bgrFrame->data[0]) { + uint8_t* frameData = bgrFrame->data[0]; + if (angle == 90 || angle == -90) { + std::memmove(frameData, + frameData, // PUT HERE YOUR PROCESSED FRAME VARIABLE DATA! + static_cast<size_t>(pluginFrame->width * pluginFrame->height * 3) + * sizeof(uint8_t)); + } + + av_frame_copy_props(bgrFrame, pluginFrame); + moveFrom(pluginFrame, bgrFrame); + } + av_frame_unref(bgrFrame); + av_frame_free(&bgrFrame); \ No newline at end of file diff --git a/SDK/sdkConstants.py b/SDK/sdkConstants.py index 5c62f2c..36073df 100644 --- a/SDK/sdkConstants.py +++ b/SDK/sdkConstants.py @@ -26,10 +26,16 @@ import string pattern = re.compile(r'[\W_]+') PLUGINS_APIS = {"MEDIA_HANDLER": '1', - "CONVERSATION_HANDLER": '2'} + "MEDIA_HANDLER_AUDIO": '2', + "CONVERSATION_HANDLER": '3'} + APIS_NAMES = {"MEDIA_HANDLER": "MediaHandler", "CONVERSATION_HANDLER": "ConversationHandler"} +DATA_TYPES = {"VIDEO": 'Video', + "AUDIO": 'Audio', + "TEXT": 'Conversation'} + ACTIONS = {"CREATE": '1', "CREATE_MAIN": '2', "CREATE/MODIFY_MANIFEST": '3', diff --git a/SDK/skeletonSrcProfile.py b/SDK/skeletonSrcProfile.py index 6e8e7d2..1e3e110 100644 --- a/SDK/skeletonSrcProfile.py +++ b/SDK/skeletonSrcProfile.py @@ -36,10 +36,14 @@ class SkeletonSourceFiles(Preferences): Preferences.__init__(self, action) self.names = [] self.apis = [] + self.dataTypes = [] self.mainFile = self.pluginDirectory + "/main.cpp" self.newNames = [] self.globNames() self.initPackage() + with open('./Templates/defaultStrings.json') as f: + self.defaultStrings = json.load(f) + f.close() def initPackage(self): if os.path.exists(self.packageFile): @@ -155,8 +159,15 @@ class SkeletonSourceFiles(Preferences): self.names.append(name) if ("MediaHandler" in file): self.apis.append(PLUGINS_APIS["MEDIA_HANDLER"]) - if ("ConversationHandler" in file): + elif ("ConversationHandler" in file): self.apis.append(PLUGINS_APIS["CONVERSATION_HANDLER"]) + if ("Subscriber" in file): + if ("Video" in file): + self.dataTypes.append(DATA_TYPES["VIDEO"]) + elif ("Audio" in file): + self.dataTypes.append(DATA_TYPES["AUDIO"]) + elif ("Conversation" in file): + self.dataTypes.append(DATA_TYPES["TEXT"]) def createHandlers(self, split): if (len(self.names) == 0): @@ -186,6 +197,7 @@ class SkeletonSourceFiles(Preferences): print(f"\nChoose a API for functionality \"{functionName}\".") print("\nAvailable APIs: ") print("(1) video during a call (Media Handler API)") + print("(2) audio during a call (Media Handler API)") print( colored( "For more information about the API, call help preferences.", @@ -194,6 +206,10 @@ class SkeletonSourceFiles(Preferences): apiType = input("\nEnter a data type number: ") if (apiType not in PLUGINS_APIS.values()): print(colored(f"Data type '{apiType}' not valid!", "red")) + else: + self.dataTypes.append(list(DATA_TYPES.values())[int(apiType)-1]) + if (apiType == PLUGINS_APIS["MEDIA_HANDLER_AUDIO"]): + apiType = PLUGINS_APIS["MEDIA_HANDLER"] self.names.append(functionName) self.newNames.append(functionName) self.apis.append(apiType) @@ -205,7 +221,6 @@ class SkeletonSourceFiles(Preferences): for j, item in enumerate(self.apis): temp = '' localNames = self.names.copy() - localApis = self.apis.copy() if (item == PLUGINS_APIS["MEDIA_HANDLER"]): localNames[j] = self.names[j] + "MediaHandler" if (split): @@ -228,16 +243,33 @@ class SkeletonSourceFiles(Preferences): data = f.read() data = data.replace("HEADER", self.header) data = data.replace("GENERIC", self.names[j]) + data = data.replace("DATATYPE", self.dataTypes[j]) f.close() with open(f"{self.pluginDirectory}/{self.names[j]}MediaHandler.h", 'w') as f: f.write(data) f.close() - with open('./Templates/genericVideoSubscriber.h', 'r') as f: + with open('./Templates/genericMediaSubscriber.h', 'r') as f: data = f.read() data = data.replace("HEADER", self.header) data = data.replace("GENERIC", self.names[j]) + data = data.replace("DATATYPE", self.dataTypes[j]) f.close() - with open(f"{self.pluginDirectory}/{self.names[j]}VideoSubscriber.h", 'w') as f: + data = data.split("---") + for k, dataItem in enumerate(data): + if (f"{self.dataTypes[j]}INCLUDES" in dataItem): + tempString = data[k] + data[k] = "" + if (self.defaultStrings["genericmediasubscriber"]["header"][f"{self.dataTypes[j]}INCLUDES"]): + for string in self.defaultStrings["genericmediasubscriber"]["header"][f"{self.dataTypes[j]}INCLUDES"]: + data[k] += tempString.replace(f"{self.dataTypes[j]}INCLUDES", string) + elif (f"{self.dataTypes[j]}PRIVATE" in dataItem): + tempString = data[k] + data[k] = "" + if (self.defaultStrings["genericmediasubscriber"]["header"][f"{self.dataTypes[j]}PRIVATE"]): + for string in self.defaultStrings["genericmediasubscriber"]["header"][f"{self.dataTypes[j]}PRIVATE"]: + data[k] += tempString.replace(f"{self.dataTypes[j]}PRIVATE", string) + data = "".join(data) + with open(f"{self.pluginDirectory}/{self.names[j]}{self.dataTypes[j]}Subscriber.h", 'w') as f: f.write(data) f.close() elif (item == PLUGINS_APIS["CONVERSATION_HANDLER"]): @@ -259,16 +291,44 @@ class SkeletonSourceFiles(Preferences): data = data.replace("HEADER", self.header) data = data.replace("PLUGINNAME", self.pluginName) data = data.replace("GENERIC", self.names[j]) + data = data.replace("DATATYPE", self.dataTypes[j]) + data = data.replace("DataType", self.dataTypes[j].lower()) f.close() with open(f"{self.pluginDirectory}/{self.names[j]}MediaHandler.cpp", 'w') as f: f.write(data) f.close() - with open('./Templates/genericVideoSubscriber.cpp', 'r') as f: + with open('./Templates/genericMediaSubscriber.cpp', 'r') as f: data = f.read() data = data.replace("HEADER", self.header) data = data.replace("GENERIC", self.names[j]) + data = data.replace("DATATYPE", self.dataTypes[j]) f.close() - with open(f"{self.pluginDirectory}/{self.names[j]}VideoSubscriber.cpp", 'w') as f: + data = data.split("---") + for k, dataItem in enumerate(data): + if (f"FFMPEG{self.dataTypes[j]}INCLUDES" in dataItem): + tempString = data[k] + tempStringSplits = tempString.split("\n")[1:] + data[k] = "" + if (self.defaultStrings["genericmediasubscriber"]["impl"][f"FFMPEG{self.dataTypes[j]}INCLUDES"]): + for string in self.defaultStrings["genericmediasubscriber"]["impl"][f"FFMPEG{self.dataTypes[j]}INCLUDES"]: + data[k] += tempStringSplits[1].replace(f"FFMPEG{self.dataTypes[j]}INCLUDES", string) + "\n" + tempStringSplits[1] = data[k] + data[k] = tempStringSplits[0] + "\n" + tempStringSplits[1] + tempStringSplits[2] + elif (f"{self.dataTypes[j]}INCLUDES" in dataItem): + tempString = data[k] + data[k] = "" + if (self.defaultStrings["genericmediasubscriber"]["impl"][f"{self.dataTypes[j]}INCLUDES"]): + for string in self.defaultStrings["genericmediasubscriber"]["impl"][f"{self.dataTypes[j]}INCLUDES"]: + data[k] += tempString.replace(f"{self.dataTypes[j]}INCLUDES", string) + elif (f"{self.dataTypes[j]}UPDATE" in dataItem): + fileName = self.defaultStrings["genericmediasubscriber"]["impl"][f"{self.dataTypes[j]}UPDATE"] + with open(f"./Templates/{fileName}") as updateFile: + updateTxt = updateFile.read() + updateFile.close() + data[k] = data[k].replace(f"{self.dataTypes[j]}UPDATE", updateTxt) + + data = "".join(data) + with open(f"{self.pluginDirectory}/{self.names[j]}{self.dataTypes[j]}Subscriber.cpp", 'w') as f: f.write(data) f.close() elif (item == PLUGINS_APIS["CONVERSATION_HANDLER"]): @@ -373,13 +433,9 @@ class SkeletonSourceFiles(Preferences): self.package["version"] = '0.0.0' f.close() - with open('./Templates/defaultDependenciesStrings.json') as f: - defaultStrings = json.load(f) - f.close() - for api in self.apis: if api == PLUGINS_APIS["MEDIA_HANDLER"]: - for dep in defaultStrings["package.json"]["MediaHandler"]["deps"]: + for dep in self.defaultStrings["package.json"]["MediaHandler"]["deps"]: if dep not in self.package["deps"]: self.package["deps"].append(dep) with open(f"{self.pluginDirectory}/package.json", 'w') as f: @@ -397,31 +453,54 @@ class SkeletonSourceFiles(Preferences): outputStr += baseStr.replace(key, name) return outputStr - def fillBuildFile(self, inputStr): + def fillBuildFile(self, inputStr, fileType): #fileType = 0 -> build.sh; fileType = 1 -> CMakeLists.txt inputStr = inputStr.replace('PLUGINNAME', self.pluginName) inputStr = inputStr.replace('MANIFESTVERSION', self.version) splits = inputStr.split('---') tempPart = [] for i, split in enumerate(splits): - if (("FFMPEG" in split or "avutil" in split) + if ("FFMPEG" in split and PLUGINS_APIS['MEDIA_HANDLER'] not in self.apis): splits[i] = '' elif ("CPPFILENAME" in split): splits[i] = self.globFiles(split, "CPPFILENAME", "cpp") elif ("HFILENAME" in split): splits[i] = self.globFiles(split, "HFILENAME", "h") + elif ("FFMPEGEXTRA" in split): + splits[i] = splits[i].replace("FFMPEGEXTRA", "") elif ("FFMPEGCPP" in split): - splits[i] = split.replace("FFMPEGCPP", '') + tempString = splits[i] + splits[i] = "" + for item in self.defaultStrings["buildFiles"]["MediaHandler"][f"{self.ffmpegBuildOption}FFMPEGCPP"]: + splits[i] += tempString.replace("FFMPEGCPP", item) elif ("FFMPEGH" in split): - splits[i] = split.replace("FFMPEGH", '') + tempString = splits[i] + splits[i] = "" + for item in self.defaultStrings["buildFiles"]["MediaHandler"][f"{self.ffmpegBuildOption}FFMPEGH"]: + splits[i] += tempString.replace("FFMPEGH", item) + elif ("FFMPEGLIBS" in split): + tempString = splits[i] + splits[i] = "" + for item in self.defaultStrings["buildFiles"]["MediaHandler"][f"{self.ffmpegBuildOption}FFMPEGLIBS"]: + if (fileType): + splits[i] += tempString.replace("FFMPEGLIBS", f"{item} ") + else: + splits[i] += tempString.replace("FFMPEGLIBS", f"-l:lib{item}.a") inputStr = ''.join(splits) return inputStr def createBuildFiles(self): + self.ffmpegBuildOption = None + for typeItem in self.dataTypes: + if (typeItem == DATA_TYPES["VIDEO"]): + self.ffmpegBuildOption = 'Video' + break + elif (typeItem == DATA_TYPES["AUDIO"]): + self.ffmpegBuildOption = 'Audio' with open("./Templates/CMakeLists.txt", 'r') as f: cmakelists = f.read() f.close() - cmakelists = self.fillBuildFile(cmakelists) + cmakelists = self.fillBuildFile(cmakelists, 1) with open(self.cmakelistsFile, 'w') as f: f.write(cmakelists) f.close() @@ -429,7 +508,7 @@ class SkeletonSourceFiles(Preferences): with open("./Templates/build.sh", 'r') as f: build = f.read() f.close() - build = self.fillBuildFile(build) + build = self.fillBuildFile(build, 0) with open(self.buildFile, 'w') as f: f.write(build) f.close() -- GitLab