SDK: add audio option for MediaHandler API

- modify AudioFilter for Windows build

Change-Id: Icddd014b0d42cd3848000c7b8b97baa7cab709aa
GitLab: #3
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 @@
 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_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 @@
                                         ---${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 @@
     -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 @@
         -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 @@
     , 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 @@
 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 @@
 
 #pragma once
 
-#include "GENERICVideoSubscriber.h"
+#include "GENERICDATATYPESubscriber.h"
 
 #include "plugin/jamiplugin.h"
 #include "plugin/mediahandler.h"
@@ -24,7 +24,7 @@
     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 @@
 #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 @@
     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 @@
 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 @@
         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 @@
                         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 @@
                 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 @@
                 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 @@
         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 @@
                         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 @@
                         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 @@
                 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 @@
             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 @@
         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()