Skip to content
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
67 changes: 67 additions & 0 deletions MutedStreamReplicator/.classpath
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry including="**/*.java" kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="optional" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="test" value="true"/>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="test" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="optional" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/main/webapp">
<attributes>
<attribute name="test" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="optional" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
<attributes>
<attribute name="module" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="target/generated-sources/annotations">
<attributes>
<attribute name="ignore_optional_problems" value="true"/>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="m2e-apt" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
<attributes>
<attribute name="ignore_optional_problems" value="true"/>
<attribute name="test" value="true"/>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="m2e-apt" value="true"/>
</attributes>
</classpathentry>
<classpathentry combineaccessrules="false" kind="src" path="/ant-media-enterprise"/>
<classpathentry combineaccessrules="false" kind="src" path="/ant-media-server"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
8 changes: 8 additions & 0 deletions MutedStreamReplicator/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/target/
./target/*
/.classpath
/.project
/.settings/
/src/main/java/io/antmedia/plugin/*.js
/log/
.idea
34 changes: 34 additions & 0 deletions MutedStreamReplicator/.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>MutedStreamReplicator</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
<filteredResources>
<filter>
<id>1773393856443</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>
65 changes: 65 additions & 0 deletions MutedStreamReplicator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# MutedStreamReplicator

`MutedStreamReplicator` creates a muted companion stream for each published source stream by republishing it to the same application with the `-muted` suffix.

Example:

- Source stream: `liveStream1`
- Muted replica stream: `liveStream1-muted`

The plugin listens for stream lifecycle events, starts a local RTMP endpoint for the muted replica, disables audio and video ingest on the replica stream itself, and then mirrors muxer output from the original enterprise transcoding pipeline into the replica pipeline.

## Requirements

- Ant Media Server Enterprise
- Maven
- Java version compatible with your Ant Media Server build

This plugin depends on `EncoderAdaptor`, so it is intended for transcoding-enabled flows.

## Build

```sh
mvn clean install -Dgpg.skip=true
```

## Install

Copy the generated plugin jar into your Ant Media Server plugins directory:

```sh
cp target/MutedStreamReplicator.jar /usr/local/antmedia/plugins/
```

Restart Ant Media Server after copying the jar:

```sh
sudo service antmedia restart
```

## How It Works

1. When a source stream starts, the plugin asks Ant Media Server to publish a local RTMP endpoint named `<streamId>-muted`.
2. When that muted replica stream starts, the plugin disables direct ingest on the replica adaptor.
3. The plugin attaches lightweight receiver muxers to the source stream and matching rendition encoders.
4. Those receivers forward packets into the target stream's muxers, producing a muted copy of the source stream.

## Notes

- The muted replica stream id suffix is `-muted`.
- The plugin only manages lifecycle for streams it starts through this suffix convention.
- If the source or target adaptor is not an `EncoderAdaptor`, the plugin logs a warning and skips wiring.

## Logs

Useful logs can be watched with:

```sh
tail -f /usr/local/antmedia/log/ant-media-server.log
```

Typical messages include:

- `Started muted replica stream: <streamId>-muted`
- `Muted replica stream started: <streamId>-muted`
- `Failed to start muted replica stream ...`
23 changes: 23 additions & 0 deletions MutedStreamReplicator/mvn-settings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<settings>
<servers>
<server>
<id>ossrh</id>
<username>${env.CI_DEPLOY_USERNAME}</username>
<password>${env.CI_DEPLOY_PASSWORD}</password>
</server>
</servers>

<profiles>
<profile>
<id>ossrh</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<gpg.executable>gpg</gpg.executable>
<gpg.keyname>${env.GPG_KEY_NAME}</gpg.keyname>
<gpg.passphrase>${env.GPG_PASSPHRASE}</gpg.passphrase>
</properties>
</profile>
</profiles>
</settings>
Loading
Loading