-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
- Loading branch information
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
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:. |
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/ | ||
python setup.py build_ext --inplace | ||
cd ../../../ | ||
|
||
cp ./src/main/python/libpythonWrapper.cpython-313-x86_64-linux-gnu.so /usr/local/antmedia/lib/native-linux-x86_64/ | ||
|
||
rm -r $AMS_DIR/plugins/pythonplugin* | ||
cp target/PythonPlugin.jar $AMS_DIR/plugins/ | ||
|
||
OUT=$? | ||
|
||
if [ $OUT -ne 0 ]; then | ||
exit $OUT | ||
fi | ||
cd $AMS_DIR | ||
./start-debug.sh |
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" }); | ||
} | ||
} |
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-linux-x86_64/libpythonWrapper.cpython-313-x86_64-linux-gnu.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()"); | ||
} | ||
|
||
} |