具有多个网络接口的FFmpeg多播

时间:2018-08-27 09:56:53

标签: networking ffmpeg multicast

我有Java应用程序作为FFmpeg的包装器。我需要捕获mp2多播流,将其转换为mp3,然后将转换后的多播流发送到另一个地址。 它运作良好。但是现在我有两个网络接口。其中一个用于Internet /本地网络(eth1)。需要配置第二个网络接口(eth2)来捕获和发送多播流。

但是ffmpeg默认尝试从第一个网络接口捕获。我可以在tcpdump中看到数据包,但是ffmpeg不能从eth2捕获它。

如何指定用于流捕获的接口和用于流发送的接口?

1 个答案:

答案 0 :(得分:0)

此问题已通过smcroute实用程序解决。

application.properties:

smcroute.config.file                        = /etc/smcroute.conf

RoutingConfig.java:

public class RoutingConfig {

    private final File file;

    public RoutingConfig(String filename) {
        this.file = new File(filename);
    }

    public List<RoutingRecord> read() throws IOException {
        List<String> lines = Files.readAllLines(file.toPath());
        return lines.stream().map(RoutingRecord::new).collect(Collectors.toList());
    }

    public void write(List<RoutingRecord> records) throws IOException {
        List<String> lines = records.stream().map(RoutingRecord::toString).collect(Collectors.toList());
        Files.write(file.toPath(), lines);
    }
}

RoutingRecord.java:

public class RoutingRecord {

    private String sourceInterface;
    private String multicastAddress;
    private String sourceMulticastAddress;
    private List<String> destinationInterfaces;

    public RoutingRecord() {
    }

    public RoutingRecord(String line) {

        String[] words = line.split(" ");

        this.sourceInterface        = words[2];
        this.multicastAddress       = words[4];
        this.sourceMulticastAddress = words[6];
        this.destinationInterfaces  = new ArrayList<>(Arrays.asList(words).subList(8, words.length));
    }

    public RoutingRecord(String sourceInterface,
                     String multicastAddress,
                     String sourceMulticastAddress,
                     List<String> destinationInterfaces
    ) {
        this.sourceInterface        = sourceInterface;
        this.multicastAddress       = multicastAddress;
        this.sourceMulticastAddress = sourceMulticastAddress;
        this.destinationInterfaces  = destinationInterfaces;
    }

    public String getSourceInterface() {return sourceInterface;}

    public String getMulticastAddress() {return multicastAddress;}

    public String getSourceMulticastAddress() {return sourceMulticastAddress;}

    public List<String> getDestinationInterfaces() {return destinationInterfaces;}

    public String getDestinationInterfacesLine() {return String.join(", ", destinationInterfaces);}

    public RoutingRecord setSourceInterface(String sourceInterface) {
        this.sourceInterface = sourceInterface;
        return this;
    }

    public RoutingRecord setMulticastAddress(String multicastAddress) {
        this.multicastAddress = multicastAddress;
        return this;
    }

    public RoutingRecord setSourceMulticastAddress(String sourceMulticastAddress) {
        this.sourceMulticastAddress = sourceMulticastAddress;
        return this;
    }

    public RoutingRecord setDestinationInterfaces(List<String> destinationInterfaces) {
        this.destinationInterfaces = destinationInterfaces;
        return this;
    }

    @Override
    public String toString() {
        return "mroute from " + sourceInterface + " " +
                "group " + multicastAddress + " " +
                "source " + sourceMulticastAddress + " " +
                "to " + String.join(" ", destinationInterfaces);
    }

RoutingServiceImpl.java:

@Service
public class RoutingServiceImpl implements RoutingService {

    private final Environment environment;

    @Autowired
    public RoutingServiceImpl(Environment environment) {
        this.environment = environment;
    }

    @Override
    public List<RoutingRecord> getRoutingLines() throws IOException {
        String filename             = environment.getProperty("smcroute.config.file");
        RoutingConfig routingConfig = new RoutingConfig(filename);
        return routingConfig.read();
    }

    @Override
    public void saveRoutingLines(List<RoutingRecord> records) throws IOException {
        String filename = environment.getProperty("smcroute.config.file");
        RoutingConfig routingConfig = new RoutingConfig(filename);
        routingConfig.write(records);
    }

    @Override
    public void saveRoutingLine(RoutingRecord routingRecord) throws IOException {
        String filename = environment.getProperty("smcroute.config.file");
        RoutingConfig routingConfig = new RoutingConfig(filename);

        List<RoutingRecord> records = routingConfig.read();
        records.add(routingRecord);

        routingConfig.write(records);
    }

    @Override
    public void applyRoutes() throws IOException {

        Runtime rt = Runtime.getRuntime();

        rt.exec(new String[] {
                "service",
                "smcroute",
                "restart"
        });
    }
}