Skip to content

Commit

Permalink
add new python plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
USAMAWIZARD committed Feb 14, 2025
1 parent e782970 commit 2b83977
Show file tree
Hide file tree
Showing 37 changed files with 36,509 additions and 638 deletions.
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:.
10 changes: 10 additions & 0 deletions PythonPlugin/install_dev_dependencies.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#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-get install python3-dev
sudo pip3 install cython numpy opencv-python
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=/home/usama/tem/ant-media-server/
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);

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 null;
}

@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 null;
}

@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

0 comments on commit 2b83977

Please sign in to comment.