package com.github.sarxos.webcam.ds.gstreamer;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import org.gstreamer.Element;
import org.gstreamer.ElementFactory;
import org.gstreamer.Gst;
import org.gstreamer.interfaces.PropertyProbe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.github.sarxos.webcam.WebcamDevice;
import com.github.sarxos.webcam.WebcamDriver;
import com.github.sarxos.webcam.WebcamException;
import com.github.sarxos.webcam.util.NixVideoDevUtils;
import com.sun.jna.NativeLibrary;
import com.sun.jna.Platform;
/**
* GStreamer capture driver.
*
* @author Bartosz Firyn (sarxos)
*/
public class GStreamerDriver implements WebcamDriver {
private static final Logger LOG = LoggerFactory.getLogger(GStreamerDriver.class);
private static final class GStreamerShutdownHook extends Thread {
public GStreamerShutdownHook() {
super("gstreamer-shutdown-hook");
}
@Override
public void run() {
LOG.debug("GStreamer deinitialization");
Gst.deinit();
}
}
private static final AtomicBoolean INITIALIZED = new AtomicBoolean(false);
public GStreamerDriver() {
if (INITIALIZED.compareAndSet(false, true)) {
init();
}
}
private static final void init() {
if (!Platform.isWindows() && !Platform.isLinux()) {
throw new WebcamException(String.format("%s has been designed to work only on Windows and Linux platforms", GStreamerDriver.class.getSimpleName()));
}
LOG.debug("GStreamer initialization");
String gpath = null;
if (Platform.isWindows()) {
String path = System.getenv("PATH");
for (String p : path.split(";")) {
LOG.trace("Search %PATH% for gstreamer bin {}", p);
if (p.indexOf("GStreamer\\v0.10.") != -1) {
gpath = p;
break;
}
}
if (gpath != null) {
LOG.debug("Add bin directory to JNA search paths {}", gpath);
NativeLibrary.addSearchPath("gstreamer-0.10", gpath);
} else {
throw new WebcamException(String.format("GStreamer has not been installed or not available in PATH: %s", path));
}
}
//@formatter:off
String[] args = new String[] {
// "--gst-plugin-path", new File(".").getAbsolutePath(),
// "--gst-debug-level=3",
};
//@formatter:on
Gst.init(GStreamerDriver.class.getSimpleName(), args);
Runtime.getRuntime().addShutdownHook(new GStreamerShutdownHook());
}
@Override
public List<WebcamDevice> getDevices() {
List<WebcamDevice> devices = new ArrayList<WebcamDevice>();
String srcname = null;
if (Platform.isWindows()) {
srcname = "dshowvideosrc";
} else if (Platform.isLinux()) {
srcname = "v4l2src";
} else if (Platform.isMac()) {
srcname = "qtkitvideosrc";
}
Element src = ElementFactory.make(srcname, "source");
try {
if (Platform.isWindows()) {
PropertyProbe probe = PropertyProbe.wrap(src);
for (Object name : probe.getValues("device-name")) {
devices.add(new GStreamerDevice(name.toString()));
}
} else if (Platform.isLinux()) {
for (File vfile : NixVideoDevUtils.getVideoFiles()) {
devices.add(new GStreamerDevice(vfile));
}
} else {
throw new RuntimeException("Platform unsupported by GStreamer capture driver");
}
} finally {
if (src != null) {
src.dispose();
}
}
return devices;
}
@Override
public boolean isThreadSafe() {
return false;
}
@Override
public String toString() {
return getClass().getSimpleName();
}
}