Skip to content
Snippets Groups Projects
Commit f499e076 authored by Aline Gondim Santos's avatar Aline Gondim Santos
Browse files

SDK: add audio option for MediaHandler API

- modify AudioFilter for Windows build

Change-Id: Icddd014b0d42cd3848000c7b8b97baa7cab709aa
GitLab: #3
parent c9181b4c
Branches
Tags
No related merge requests found
Showing with 305 additions and 60 deletions
...@@ -68,7 +68,7 @@ target_link_directories(${ProjectName} PUBLIC ${CONTRIB_PATH} ...@@ -68,7 +68,7 @@ target_link_directories(${ProjectName} PUBLIC ${CONTRIB_PATH}
${FFMPEG}/bin ${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( add_custom_command(
TARGET ${ProjectName} TARGET ${ProjectName}
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include "filterAudioSubscriber.h" #include "filterAudioSubscriber.h"
extern "C" { extern "C" {
#include <libavutil/display.h>
#include <libavcodec/avcodec.h> #include <libavcodec/avcodec.h>
#include <libavformat/avformat.h> #include <libavformat/avformat.h>
#include <libavfilter/buffersrc.h> #include <libavfilter/buffersrc.h>
......
...@@ -7,6 +7,7 @@ multiple functionalities. ...@@ -7,6 +7,7 @@ multiple functionalities.
Each functionality may be applied to different data types that requires Each functionality may be applied to different data types that requires
diferent APIs. Currently, our plugin system supports the following data: diferent APIs. Currently, our plugin system supports the following data:
(1) video during a call (Media Handler API). (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 Be aware that when creating functionalities outside a full plugin pipeline
......
...@@ -38,15 +38,12 @@ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") ...@@ -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(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
set(plugin_SRC ---CPPFILENAME set(plugin_SRC ---CPPFILENAME
---../lib/accel.cppFFMPEGCPP ---FFMPEGCPP
../lib/frameUtils.cpp
---) ---)
set(plugin_HDR ---HFILENAME set(plugin_HDR ---HFILENAME
---../lib/accel.hFFMPEGH ---FFMPEGH
../lib/frameScaler.h ---./../lib/pluglog.h
../lib/frameUtils.h
---../lib/pluglog.h
) )
add_library(${ProjectName} SHARED ${plugin_SRC} add_library(${ProjectName} SHARED ${plugin_SRC}
...@@ -64,7 +61,7 @@ target_link_directories(${ProjectName} PUBLIC ${CONTRIB_PATH} ...@@ -64,7 +61,7 @@ target_link_directories(${ProjectName} PUBLIC ${CONTRIB_PATH}
---${FFMPEG}/bin--- ---${FFMPEG}/bin---
) )
target_link_libraries(${ProjectName} PUBLIC ---swscale avutil---) target_link_libraries(${ProjectName} PUBLIC ---FFMPEGLIBS---)
add_custom_command( add_custom_command(
TARGET ${ProjectName} TARGET ${ProjectName}
......
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
...@@ -63,12 +63,11 @@ then ...@@ -63,12 +63,11 @@ then
-I"${DAEMON_SRC}" \ -I"${DAEMON_SRC}" \
-I"${CONTRIB_PATH}/${CONTRIB_PLATFORM}/include" \ -I"${CONTRIB_PATH}/${CONTRIB_PLATFORM}/include" \
-I"${PLUGINS_LIB}" \ -I"${PLUGINS_LIB}" \
---FFMPEGCPP./../lib/accel.cpp \ ---FFMPEGCPP \
---CPPFILENAME \ ---CPPFILENAME \
----L"${CONTRIB_PATH}/${CONTRIB_PLATFORM}/lib/" \ ----L"${CONTRIB_PATH}/${CONTRIB_PLATFORM}/lib/" \
----l:libswscale.a \ ----FFMPEGLIBS \
-l:libavutil.a \ ---FFMPEGEXTRA-lva \
-lva \
----o "build-local/jpl/lib/${CONTRIB_PLATFORM_CURT}-linux-gnu/${SO_FILE_NAME}" ----o "build-local/jpl/lib/${CONTRIB_PLATFORM_CURT}-linux-gnu/${SO_FILE_NAME}"
elif [ "${PLATFORM}" = "android" ] elif [ "${PLATFORM}" = "android" ]
...@@ -185,11 +184,10 @@ then ...@@ -185,11 +184,10 @@ then
-I"${DAEMON_SRC}" \ -I"${DAEMON_SRC}" \
-I"${CONTRIB_PATH}/${CONTRIB_PLATFORM}/include" \ -I"${CONTRIB_PATH}/${CONTRIB_PLATFORM}/include" \
-I"${PLUGINS_LIB}" \ -I"${PLUGINS_LIB}" \
---FFMPEGCPP./../lib/accel.cpp \ ---FFMPEGCPP \
---CPPFILENAME \ ---CPPFILENAME \
----L"${CONTRIB_PATH}/${CONTRIB_PLATFORM}/lib/" \ ----L"${CONTRIB_PATH}/${CONTRIB_PLATFORM}/lib/" \
----lswscale \ ----FFMPEGLIBS \
-lavutil \
----llog -lz \ ----llog -lz \
--sysroot=$ANDROID_SYSROOT \ --sysroot=$ANDROID_SYSROOT \
-o "build-local/jpl/lib/$CURRENT_ABI/${SO_FILE_NAME}" -o "build-local/jpl/lib/$CURRENT_ABI/${SO_FILE_NAME}"
......
{
"package.json":
{
"MediaHandler": {
"deps": [
"ffmpeg"
]
}
}
}
\ No newline at end of file
{
"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
...@@ -17,27 +17,26 @@ GENERICMediaHandler::GENERICMediaHandler(std::map<std::string, std::string>&& pp ...@@ -17,27 +17,26 @@ GENERICMediaHandler::GENERICMediaHandler(std::map<std::string, std::string>&& pp
, ppm_ {ppm} , ppm_ {ppm}
{ {
setId(datapath_); setId(datapath_);
mVS = std::make_shared<GENERICVideoSubscriber>(datapath_); mediaSubscriber_ = std::make_shared<GENERICDATATYPESubscriber>(datapath_);
} }
void void
GENERICMediaHandler::notifyAVFrameSubject(const StreamData& data, jami::avSubjectPtr subject) GENERICMediaHandler::notifyAVFrameSubject(const StreamData& data, jami::avSubjectPtr subject)
{ {
Plog::log(Plog::LogPriority::INFO, TAG, "IN AVFRAMESUBJECT");
std::ostringstream oss; std::ostringstream oss;
std::string direction = data.direction ? "Receive" : "Preview"; std::string direction = data.direction ? "Receive" : "Preview";
oss << "NEW SUBJECT: [" << data.id << "," << direction << "]" << std::endl; oss << "NEW SUBJECT: [" << data.id << "," << direction << "]" << std::endl;
bool preferredStreamDirection = false; // false for output; true for input bool preferredStreamDirection = false; // false for output; true for input
oss << "preferredStreamDirection " << preferredStreamDirection << std::endl; oss << "preferredStreamDirection " << preferredStreamDirection << std::endl;
if (data.type == StreamType::video && !data.direction if (data.type == StreamType::DataType && !data.direction
&& data.direction == preferredStreamDirection) { && data.direction == preferredStreamDirection) {
subject->attach(mVS.get()); // your image subject->attach(mediaSubscriber_.get()); // your image
oss << "got my sent image attached" << std::endl; oss << "got my sent image attached" << std::endl;
attached_ = "1"; attached_ = "1";
} else if (data.type == StreamType::video && data.direction } else if (data.type == StreamType::DataType && data.direction
&& data.direction == preferredStreamDirection) { && 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; oss << "got received image attached" << std::endl;
attached_ = "1"; attached_ = "1";
} }
...@@ -79,7 +78,7 @@ void ...@@ -79,7 +78,7 @@ void
GENERICMediaHandler::detach() GENERICMediaHandler::detach()
{ {
attached_ = "0"; attached_ = "0";
mVS->detach(); mediaSubscriber_->detach();
} }
GENERICMediaHandler::~GENERICMediaHandler() GENERICMediaHandler::~GENERICMediaHandler()
......
...@@ -2,7 +2,7 @@ HEADER ...@@ -2,7 +2,7 @@ HEADER
#pragma once #pragma once
#include "GENERICVideoSubscriber.h" #include "GENERICDATATYPESubscriber.h"
#include "plugin/jamiplugin.h" #include "plugin/jamiplugin.h"
#include "plugin/mediahandler.h" #include "plugin/mediahandler.h"
...@@ -24,7 +24,7 @@ public: ...@@ -24,7 +24,7 @@ public:
virtual void setPreferenceAttribute(const std::string& key, const std::string& value) override; virtual void setPreferenceAttribute(const std::string& key, const std::string& value) override;
virtual bool preferenceMapHasKey(const std::string& key) 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_; } const std::string& dataPath() const { return datapath_; }
......
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
...@@ -6,15 +6,16 @@ extern "C" { ...@@ -6,15 +6,16 @@ extern "C" {
#include <libavutil/frame.h> #include <libavutil/frame.h>
} }
#include <observer.h> #include <observer.h>
#include <frameScaler.h> ---DATATYPEINCLUDES
---
namespace jami { namespace jami {
class GENERICVideoSubscriber : public jami::Observer<AVFrame*> class GENERICDATATYPESubscriber : public jami::Observer<AVFrame*>
{ {
public: public:
GENERICVideoSubscriber(const std::string& dataPath); GENERICDATATYPESubscriber(const std::string& dataPath);
~GENERICVideoSubscriber(); ~GENERICDATATYPESubscriber();
virtual void update(jami::Observable<AVFrame*>*, AVFrame* const&) override; virtual void update(jami::Observable<AVFrame*>*, AVFrame* const&) override;
virtual void attached(jami::Observable<AVFrame*>*) override; virtual void attached(jami::Observable<AVFrame*>*) override;
...@@ -27,9 +28,9 @@ private: ...@@ -27,9 +28,9 @@ private:
Observable<AVFrame*>* observable_ = nullptr; Observable<AVFrame*>* observable_ = nullptr;
// Data // Data
std::string path_; std::string path_;---
FrameScaler scaler; DATATYPEPRIVATE
---
// Status variables of the processing // Status variables of the processing
bool firstRun {true}; bool firstRun {true};
}; };
......
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
...@@ -26,10 +26,16 @@ import string ...@@ -26,10 +26,16 @@ import string
pattern = re.compile(r'[\W_]+') pattern = re.compile(r'[\W_]+')
PLUGINS_APIS = {"MEDIA_HANDLER": '1', PLUGINS_APIS = {"MEDIA_HANDLER": '1',
"CONVERSATION_HANDLER": '2'} "MEDIA_HANDLER_AUDIO": '2',
"CONVERSATION_HANDLER": '3'}
APIS_NAMES = {"MEDIA_HANDLER": "MediaHandler", APIS_NAMES = {"MEDIA_HANDLER": "MediaHandler",
"CONVERSATION_HANDLER": "ConversationHandler"} "CONVERSATION_HANDLER": "ConversationHandler"}
DATA_TYPES = {"VIDEO": 'Video',
"AUDIO": 'Audio',
"TEXT": 'Conversation'}
ACTIONS = {"CREATE": '1', ACTIONS = {"CREATE": '1',
"CREATE_MAIN": '2', "CREATE_MAIN": '2',
"CREATE/MODIFY_MANIFEST": '3', "CREATE/MODIFY_MANIFEST": '3',
......
...@@ -36,10 +36,14 @@ class SkeletonSourceFiles(Preferences): ...@@ -36,10 +36,14 @@ class SkeletonSourceFiles(Preferences):
Preferences.__init__(self, action) Preferences.__init__(self, action)
self.names = [] self.names = []
self.apis = [] self.apis = []
self.dataTypes = []
self.mainFile = self.pluginDirectory + "/main.cpp" self.mainFile = self.pluginDirectory + "/main.cpp"
self.newNames = [] self.newNames = []
self.globNames() self.globNames()
self.initPackage() self.initPackage()
with open('./Templates/defaultStrings.json') as f:
self.defaultStrings = json.load(f)
f.close()
def initPackage(self): def initPackage(self):
if os.path.exists(self.packageFile): if os.path.exists(self.packageFile):
...@@ -155,8 +159,15 @@ class SkeletonSourceFiles(Preferences): ...@@ -155,8 +159,15 @@ class SkeletonSourceFiles(Preferences):
self.names.append(name) self.names.append(name)
if ("MediaHandler" in file): if ("MediaHandler" in file):
self.apis.append(PLUGINS_APIS["MEDIA_HANDLER"]) self.apis.append(PLUGINS_APIS["MEDIA_HANDLER"])
if ("ConversationHandler" in file): elif ("ConversationHandler" in file):
self.apis.append(PLUGINS_APIS["CONVERSATION_HANDLER"]) 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): def createHandlers(self, split):
if (len(self.names) == 0): if (len(self.names) == 0):
...@@ -186,6 +197,7 @@ class SkeletonSourceFiles(Preferences): ...@@ -186,6 +197,7 @@ class SkeletonSourceFiles(Preferences):
print(f"\nChoose a API for functionality \"{functionName}\".") print(f"\nChoose a API for functionality \"{functionName}\".")
print("\nAvailable APIs: ") print("\nAvailable APIs: ")
print("(1) video during a call (Media Handler API)") print("(1) video during a call (Media Handler API)")
print("(2) audio during a call (Media Handler API)")
print( print(
colored( colored(
"For more information about the API, call help preferences.", "For more information about the API, call help preferences.",
...@@ -194,6 +206,10 @@ class SkeletonSourceFiles(Preferences): ...@@ -194,6 +206,10 @@ class SkeletonSourceFiles(Preferences):
apiType = input("\nEnter a data type number: ") apiType = input("\nEnter a data type number: ")
if (apiType not in PLUGINS_APIS.values()): if (apiType not in PLUGINS_APIS.values()):
print(colored(f"Data type '{apiType}' not valid!", "red")) 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.names.append(functionName)
self.newNames.append(functionName) self.newNames.append(functionName)
self.apis.append(apiType) self.apis.append(apiType)
...@@ -205,7 +221,6 @@ class SkeletonSourceFiles(Preferences): ...@@ -205,7 +221,6 @@ class SkeletonSourceFiles(Preferences):
for j, item in enumerate(self.apis): for j, item in enumerate(self.apis):
temp = '' temp = ''
localNames = self.names.copy() localNames = self.names.copy()
localApis = self.apis.copy()
if (item == PLUGINS_APIS["MEDIA_HANDLER"]): if (item == PLUGINS_APIS["MEDIA_HANDLER"]):
localNames[j] = self.names[j] + "MediaHandler" localNames[j] = self.names[j] + "MediaHandler"
if (split): if (split):
...@@ -228,16 +243,33 @@ class SkeletonSourceFiles(Preferences): ...@@ -228,16 +243,33 @@ class SkeletonSourceFiles(Preferences):
data = f.read() data = f.read()
data = data.replace("HEADER", self.header) data = data.replace("HEADER", self.header)
data = data.replace("GENERIC", self.names[j]) data = data.replace("GENERIC", self.names[j])
data = data.replace("DATATYPE", self.dataTypes[j])
f.close() f.close()
with open(f"{self.pluginDirectory}/{self.names[j]}MediaHandler.h", 'w') as f: with open(f"{self.pluginDirectory}/{self.names[j]}MediaHandler.h", 'w') as f:
f.write(data) f.write(data)
f.close() f.close()
with open('./Templates/genericVideoSubscriber.h', 'r') as f: with open('./Templates/genericMediaSubscriber.h', 'r') as f:
data = f.read() data = f.read()
data = data.replace("HEADER", self.header) data = data.replace("HEADER", self.header)
data = data.replace("GENERIC", self.names[j]) data = data.replace("GENERIC", self.names[j])
data = data.replace("DATATYPE", self.dataTypes[j])
f.close() 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.write(data)
f.close() f.close()
elif (item == PLUGINS_APIS["CONVERSATION_HANDLER"]): elif (item == PLUGINS_APIS["CONVERSATION_HANDLER"]):
...@@ -259,16 +291,44 @@ class SkeletonSourceFiles(Preferences): ...@@ -259,16 +291,44 @@ class SkeletonSourceFiles(Preferences):
data = data.replace("HEADER", self.header) data = data.replace("HEADER", self.header)
data = data.replace("PLUGINNAME", self.pluginName) data = data.replace("PLUGINNAME", self.pluginName)
data = data.replace("GENERIC", self.names[j]) data = data.replace("GENERIC", self.names[j])
data = data.replace("DATATYPE", self.dataTypes[j])
data = data.replace("DataType", self.dataTypes[j].lower())
f.close() f.close()
with open(f"{self.pluginDirectory}/{self.names[j]}MediaHandler.cpp", 'w') as f: with open(f"{self.pluginDirectory}/{self.names[j]}MediaHandler.cpp", 'w') as f:
f.write(data) f.write(data)
f.close() f.close()
with open('./Templates/genericVideoSubscriber.cpp', 'r') as f: with open('./Templates/genericMediaSubscriber.cpp', 'r') as f:
data = f.read() data = f.read()
data = data.replace("HEADER", self.header) data = data.replace("HEADER", self.header)
data = data.replace("GENERIC", self.names[j]) data = data.replace("GENERIC", self.names[j])
data = data.replace("DATATYPE", self.dataTypes[j])
f.close() 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.write(data)
f.close() f.close()
elif (item == PLUGINS_APIS["CONVERSATION_HANDLER"]): elif (item == PLUGINS_APIS["CONVERSATION_HANDLER"]):
...@@ -373,13 +433,9 @@ class SkeletonSourceFiles(Preferences): ...@@ -373,13 +433,9 @@ class SkeletonSourceFiles(Preferences):
self.package["version"] = '0.0.0' self.package["version"] = '0.0.0'
f.close() f.close()
with open('./Templates/defaultDependenciesStrings.json') as f:
defaultStrings = json.load(f)
f.close()
for api in self.apis: for api in self.apis:
if api == PLUGINS_APIS["MEDIA_HANDLER"]: 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"]: if dep not in self.package["deps"]:
self.package["deps"].append(dep) self.package["deps"].append(dep)
with open(f"{self.pluginDirectory}/package.json", 'w') as f: with open(f"{self.pluginDirectory}/package.json", 'w') as f:
...@@ -397,31 +453,54 @@ class SkeletonSourceFiles(Preferences): ...@@ -397,31 +453,54 @@ class SkeletonSourceFiles(Preferences):
outputStr += baseStr.replace(key, name) outputStr += baseStr.replace(key, name)
return outputStr 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('PLUGINNAME', self.pluginName)
inputStr = inputStr.replace('MANIFESTVERSION', self.version) inputStr = inputStr.replace('MANIFESTVERSION', self.version)
splits = inputStr.split('---') splits = inputStr.split('---')
tempPart = [] tempPart = []
for i, split in enumerate(splits): 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): and PLUGINS_APIS['MEDIA_HANDLER'] not in self.apis):
splits[i] = '' splits[i] = ''
elif ("CPPFILENAME" in split): elif ("CPPFILENAME" in split):
splits[i] = self.globFiles(split, "CPPFILENAME", "cpp") splits[i] = self.globFiles(split, "CPPFILENAME", "cpp")
elif ("HFILENAME" in split): elif ("HFILENAME" in split):
splits[i] = self.globFiles(split, "HFILENAME", "h") splits[i] = self.globFiles(split, "HFILENAME", "h")
elif ("FFMPEGEXTRA" in split):
splits[i] = splits[i].replace("FFMPEGEXTRA", "")
elif ("FFMPEGCPP" in split): 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): 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) inputStr = ''.join(splits)
return inputStr return inputStr
def createBuildFiles(self): 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: with open("./Templates/CMakeLists.txt", 'r') as f:
cmakelists = f.read() cmakelists = f.read()
f.close() f.close()
cmakelists = self.fillBuildFile(cmakelists) cmakelists = self.fillBuildFile(cmakelists, 1)
with open(self.cmakelistsFile, 'w') as f: with open(self.cmakelistsFile, 'w') as f:
f.write(cmakelists) f.write(cmakelists)
f.close() f.close()
...@@ -429,7 +508,7 @@ class SkeletonSourceFiles(Preferences): ...@@ -429,7 +508,7 @@ class SkeletonSourceFiles(Preferences):
with open("./Templates/build.sh", 'r') as f: with open("./Templates/build.sh", 'r') as f:
build = f.read() build = f.read()
f.close() f.close()
build = self.fillBuildFile(build) build = self.fillBuildFile(build, 0)
with open(self.buildFile, 'w') as f: with open(self.buildFile, 'w') as f:
f.write(build) f.write(build)
f.close() f.close()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment