Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add new python plugin #129

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion MediaPushPlugin/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
/.classpath
/.project
/.settings/

/src/main/java/io/antmedia/plugin/*.js
/log/
File renamed without changes.
46 changes: 46 additions & 0 deletions PythonPlugin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# PythonPlugin
This is a Python plugin project for Ant Media Server. You can use this project to interface with python program to modify Audio/Video data, apply AI
With this plugin you can find:
- Accessing the Ant Media Server ie. AntMediaApplicationAdaptor class
- Registration of the plugin as the PacketListener and/or FrameListener
- Consuming packets and/or frames
- REST interface implementation

# Prerequests
- Install Ant Media Server
- Install Maven

# Quick Start

- Clone the repository and go the Sample Plugin Directory
```sh
git clone https://github.com/ant-media/Plugins.git
cd Plugins/PythonPlugin/
```
- Build the Sample Plugin
```sh
sudo ./redeploy.sh
```
- Publish/unPublish a Live Stream to Ant Media Server with WebRTC/RTMP/RTSP
- Check the logs on the server side
```
tail -f /usr/local/antmedia/log/ant-media-server.log
```
You would see the following logs
```
...
...
...
io.antmedia.plugin.PythonPlugin - *************** Stream Started: streamIdXXXXX ***************
...
...
...
io.antmedia.plugin.PythonPlugin - *************** Stream Finished: streamIdXXXXX ***************
...
...
...
```

For more information about the plugins, [visit this post](https://antmedia.io/plugins-will-make-ant-media-server-more-powerful/)

-classpath jna.jar:.
25 changes: 25 additions & 0 deletions PythonPlugin/install_dev_dependencies.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ubuntu
sudo apt install openjdk-17-jdk-headless
sudo apt install maven
sudo apt install python3-pip
sudo apt-get install libavutil-dev libavfilter-dev libavformat-dev libsdl2-dev libavcodec-dev libx264-dev libxvidcore-dev libvdpau-dev libva-dev libxcb-shm0-dev libwavpack-dev libvpx-dev libvorbis-dev libogg-dev libvidstab-dev libspeex-dev libopus-dev libopencore-amrnb-dev libopencore-amrwb-dev libmp3lame-dev libfreetype6-dev libfdk-aac-dev libass-dev libbz2-dev libsoxr-dev
sudo at install ffmpeg
apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5 libjson-glib-dev gstreamer1.0-nice gstreamer1.0-pulseaudio

sudo apt install cmake
sudo apt-get install python3-dev
sudo apt-get install python3-numpy
sudo pip3 install cython
sudo pip3 uninstall opencv-python

#sudo pip3 install cython
# we need Gstreamer Support for OpenCV so build from src
git clone --branch 4.x --single-branch --recursive https://github.com/skvark/opencv-python.git
# git clone --recursive https://github.com/skvark/opencv-python.git
cd opencv-python
export CMAKE_ARGS="-DWITH_GSTREAMER=ON"
pip install --upgrade pip wheel
# this is the build step - the repo estimates it can take from 5
# mins to > 2 hrs depending on your computer hardware
pip wheel . --verbose
pip install opencv_python*.whl
File renamed without changes.
31 changes: 11 additions & 20 deletions PythonWrapperPlugin/pom.xml → PythonPlugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>io.antmedia.plugin</groupId>
<artifactId>PythonWrapperPlugin</artifactId>
<artifactId>PythonPlugin</artifactId>
<packaging>jar</packaging>
<name>PythonWrapperPlugin</name>
<name>PythonPlugin</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<developers>
<developer>
<id>mustafa</id>
<email>mustafa.boleken@antmedia.io</email>
<id>usama</id>
<email>usama.tahseen@antmedia.io</email>
</developer>
</developers>
<licenses>
Expand Down Expand Up @@ -59,7 +59,7 @@
</repository>
</distributionManagement>
<build>
<finalName>PythonWrapperApp</finalName>
<finalName>PythonPlugin</finalName>
<testSourceDirectory>src/test/java</testSourceDirectory>
<plugins>
<plugin>
Expand All @@ -85,7 +85,6 @@
</execution>
</executions>
</plugin>
<!-- <plugin> <artifactId>maven-javadoc-plugin</artifactId> </plugin> -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
Expand Down Expand Up @@ -146,6 +145,11 @@
</testResources>
</build>
<dependencies>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.16.0</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-websocket</artifactId>
Expand Down Expand Up @@ -237,21 +241,8 @@
<version>${javacpp.ffmpeg.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>5.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.2.0</version>
<scope>test</scope>
</dependency>

</dependencies>
<description>PythonWrapperPlugin for Ant Media Server</description>
<description>PluginApp for Ant Media Server</description>
<organization>
<name>Ant Media</name>
<url>http://antmedia.io</url>
Expand Down
25 changes: 25 additions & 0 deletions PythonPlugin/redeploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/sh
AMS_DIR=/usr/local/antmedia
mvn clean install -Dmaven.javadoc.skip=true -Dmaven.test.skip=true -Dgpg.skip=true
OUT=$?

if [ $OUT -ne 0 ]; then
exit $OUT
fi

cd ./src/main/python/
python3 setup.py build_ext --inplace
cd ../../../

cp ./src/main/python/libpythonWrapper.so $AMS_DIR/lib/native/

rm -r $AMS_DIR/plugins/PythonPlugin.jar
cp ./target/PythonPlugin.jar $AMS_DIR/plugins/

OUT=$?

if [ $OUT -ne 0 ]; then
exit $OUT
fi
cd $AMS_DIR
./start-debug.sh
27 changes: 27 additions & 0 deletions PythonPlugin/src/main/java/io/antmedia/app/DataMaper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package io.antmedia.app;

import java.util.List;
import com.sun.jna.Structure.*;
import com.sun.jna.Structure;

import java.util.Arrays;

@FieldOrder({ "streamId", "pipeline_type", "pipeline", "protocol", "port_number", "hostname", "language" })
public class DataMaper extends Structure {
public static class ByReference extends DataMaper implements Structure.ByReference {
}

public String streamId;
public String pipeline_type;
public String pipeline;
public String protocol;
public String port_number;
public String hostname;
public String language;

@Override
protected List<String> getFieldOrder() {
return Arrays.asList(
new String[] { "streamId", "pipeline_type", "pipeline", "protocol", "port_number", "hostname", "language" });
}
}
54 changes: 54 additions & 0 deletions PythonPlugin/src/main/java/io/antmedia/app/NativeInterface.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package io.antmedia.app;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Callback;

public class NativeInterface {

public static interface PY_WRAPPER extends Library {

PY_WRAPPER INSTANCE = Native.load("./lib/native/libpythonWrapper.so",
PY_WRAPPER.class);

public boolean Py_IsInitialized();

void init_py_and_wrapperlib();

void init_python_plugin_state();

void PyImport_ImportModule(String moduletoimport);

void pyimport_wrapperlib();

void aquirejil();

void releasejil();

void streamStarted(String streamid,int width,int height);

void streamFinished(String streamid);

void joinedTheRoom(String roomId, String streamId);

void leftTheRoom(String roomId, String streamId);

void onVideoFrame(String streamId, long pktPointer);

void onAudioFrame(String streamId, long pktPointer);

void onVideoPacket(String streamId, long pktPointer);

void onAudioPacket(String streamId, long pktPointer);

void setStreamInfo(String streamId, long codecPar, long rational, int isEnabled, int streamType); // pkt codecType
// 0=video

interface receiveDataCallback extends Callback {
void C_Callback(String streamId, String roomId, String data);
}

void registerCallback(receiveDataCallback callback);

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package io.antmedia.app;

import org.bytedeco.ffmpeg.avutil.AVFrame;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.antmedia.plugin.PythonPlugin;
import io.antmedia.plugin.api.IFrameListener;
import io.antmedia.plugin.api.StreamParametersInfo;

public class PythonWrapFrameListener implements IFrameListener {

protected static Logger logger = LoggerFactory.getLogger(PythonWrapFrameListener.class);

@Override
public AVFrame onAudioFrame(String streamId, AVFrame audioFrame) {
// NativeInterface.JNA_RTSP_SERVER.INSTANCE.aquirejil();
// NativeInterface.JNA_RTSP_SERVER.INSTANCE.onAudioFrame(streamId,
// audioFrame.address());
// NativeInterface.JNA_RTSP_SERVER.INSTANCE.releasejil();
return audioFrame;
}

@Override
public AVFrame onVideoFrame(String streamId, AVFrame videoFrame) {
NativeInterface.PY_WRAPPER.INSTANCE.aquirejil();
NativeInterface.PY_WRAPPER.INSTANCE.onVideoFrame(streamId, videoFrame.address());
NativeInterface.PY_WRAPPER.INSTANCE.releasejil();
return videoFrame;
}

@Override
public void writeTrailer(String streamId) {
}

@Override
public void setVideoStreamInfo(String streamId, StreamParametersInfo videoStreamInfo) {
}

@Override
public void setAudioStreamInfo(String streamId, StreamParametersInfo audioStreamInfo) {
}

@Override
public void start() {
logger.info("PythonFrameListener.start()");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package io.antmedia.app;

import org.bytedeco.ffmpeg.avcodec.AVPacket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.antmedia.plugin.api.IPacketListener;
import io.antmedia.plugin.api.StreamParametersInfo;

public class PythonWrapPacketListener implements IPacketListener {

protected static Logger logger = LoggerFactory.getLogger(PythonWrapPacketListener.class);

@Override
public void writeTrailer(String streamId) {
System.out.println("PythonPacketListener.writeTrailer()");
}

@Override
public AVPacket onVideoPacket(String streamId, AVPacket packet) {
NativeInterface.PY_WRAPPER.INSTANCE.aquirejil();
NativeInterface.PY_WRAPPER.INSTANCE.onVideoPacket(streamId, packet.address());
NativeInterface.PY_WRAPPER.INSTANCE.releasejil();
return packet;
}

@Override
public AVPacket onAudioPacket(String streamId, AVPacket packet) {
NativeInterface.PY_WRAPPER.INSTANCE.aquirejil();
NativeInterface.PY_WRAPPER.INSTANCE.onAudioPacket(streamId, packet.address());
NativeInterface.PY_WRAPPER.INSTANCE.releasejil();

return packet;
}

@Override
public void setVideoStreamInfo(String streamId, StreamParametersInfo videoStreamInfo) {
}

@Override
public void setAudioStreamInfo(String streamId, StreamParametersInfo audioStreamInfo) {
}

}
Loading