I've a problem with playing a mjpeg stream in vala.
I have construct my pipeline and it works with only two elements(videotestsrc and cluttersink), but if I want to add more I get an "Internal data flow error" and "streaming task paused, reason not-linked (-1)".
If I run the pipeline manually it works:
gst-launch souphttpsrc location=http://mjpeg.sanford.io/count.mjpeg ! multipartdemux ! jpegdec ! autovideosink
Here is my streaming class:
public class Stream : Clutter.Actor {
Clutter.Texture video;
public dynamic Gst.Element playbin;
public Gst.Pipeline pipeline;
public Gst.Element demux;
public Gst.Element jpegdec;
public Gst.Element outputsink;
public dynamic Gst.Element src;
public dynamic Gst.Element video_sink;
public Stream(){
print("stream");
video = new Clutter.Texture ();
this.pipeline = new Gst.Pipeline("videopipeline");
this.src = Gst.ElementFactory.make ("souphttpsrc","httpsrc");
this.demux = Gst.ElementFactory.make ("multipartdemux","demux");
this.jpegdec = Gst.ElementFactory.make ("jpegdec","jpegdec");
this.outputsink = Gst.ElementFactory.make("autovideosink","output");
this.video_sink = Gst.ElementFactory.make ("cluttersink", "source");
this.video_sink.texture = video;
this.src.set("location","http://mjpeg.sanford.io/count.mjpeg");
this.pipeline.add_many(this.src,this.demux,this.jpegdec,this.outputsink,this.video_sink);
this.src.link(this.demux);
this.demux.link(this.jpegdec);
this.jpegdec.link(this.outputsink);
this.outputsink.link(this.video_sink);
this.add_child (video);
this.pipeline.set_state(Gst.State.PLAYING);
}
}
Here is the full error log:
http://pastebin.com/b9GnA5ke
You can't have two sink elements attached to jpegdec. If you need to do that you should use the "tee" element, while making sure to use add a "queue" to each branch of the tee.
There may also be a caps issue going from jpegdec to cluttersink. I'd structure it as follows:
souphttpsrc ! multipartdemux ! jpegdec ! tee name=t ! queue ! videoconvert ! autovideosink
t. ! queue ! videoconvert ! cluttersink
Related
I have a bunch of cassandra FQL logs with the "cq4" extension. I would like to read them in Java, is there a Java class that those log entries can be mapped into?
These are the logs I see.
I want to read this with this code:
import net.openhft.chronicle.Chronicle;
import net.openhft.chronicle.ChronicleQueueBuilder;
import net.openhft.chronicle.ExcerptTailer;
import java.io.IOException;
public class Main{
public static void main(String[] args) throws IOException {
Chronicle chronicle = ChronicleQueueBuilder.indexed("/Users/pavelorekhov/Desktop/fql_logs").build();
ExcerptTailer tailer = chronicle.createTailer();
while (tailer.nextIndex()) {
tailer.readInstance(/*class goes here*/)
}
}
}
I think from the code and screenshot you can understand what kind of class I need in order to read log entries into objects. Does that class exist in some cassandra maven dependency?
You are using Chronicle 3.x, which is very old.
I suggest using Chronicle 5.20.123, which is the version Cassandra uses.
I would assume Cassandra has it's own tool for reading the contents of these file however, you can dump the raw messages with net.openhft.chronicle.queue.main.DumpMain
I ended up cloning cassandra's github repo from here: https://github.com/apache/cassandra
In their code they have the FQLQueryIterator class which you can use to read logs, like so:
SingleChronicleQueue scq = SingleChronicleQueueBuilder.builder().path("/Users/pavelorekhov/Desktop/fql_logs").build();
ExcerptTailer excerptTailer = scq.createTailer();
FQLQueryIterator iterator = new FQLQueryIterator(excerptTailer, 1);
while (iterator.hasNext()) {
FQLQuery fqlQuery = iterator.next(); // object that holds the log entry
// do whatever you need to do with that log entry...
}
I'm trying to play a sound file with gstreamer in Rust (using the gstreamer crate).
Here's my code:
gst::init().unwrap();
let source = gst::ElementFactory::make("filesrc", Some("source")).expect("Could not create source");
source.set_property_from_str("location", "/home/yuutsuna/Music/m3.mp3");
let decodebin = gst::ElementFactory::make("decodebin", Some("decodebin")).expect("Could not create decodebin element");
let audioconvert = gst::ElementFactory::make("audioconvert", Some("audioconvert")).expect("Could not create audioconvert element");
let sink = gst::ElementFactory::make("pulsesink", None).expect("SINK");
sink.set_property_from_str("device", "alsa_output.pci-0000_02_02.0.analog-stereo");
let pipeline = gst::Pipeline::new(Some("music-pipeline"));
pipeline.add_many(&[&source, &decodebin, &audioconvert, &sink]).unwrap();
gst::Element::link(&source, &decodebin).expect("could not link source and decodebin");
gst::Element::link(&decodebin, &audioconvert).expect("Could not link decodebin and audioconvert");
gst::Element::link(&audioconvert, &sink).expect("Could not link audioconvert and sink");
I get the error Could not link decodebin and audioconvert
However the following command which do the same is working:
gst-launch-1.0 filesrc location="/home/yuutsuna/Music/m3.mp3" ! decodebin ! audioconvert ! pulsesink device=alsa_output.pci-0000_02_02.0.analog-stereo
After looking into the logs and the documentation I found out gstreamer is not able to link the pads between the decodebin and the audioconvert
0:00:00.098766751 13567 0x7fd40c004600 INFO GST_ELEMENT_PADS gstutils.c:1816:gst_element_link_pads_full: trying to link element decodebin:(any) to element audioconvert:(any)
0:00:00.098808081 13567 0x7fd40c004600 INFO GST_PADS gstpad.c:4357:gst_pad_peer_query:<audioconvert:src> pad has no peer
0:00:00.098874314 13567 0x7fd40c004600 INFO structure gststructure.c:2917:gst_structure_get_valist: Expected field 'channel-mask' in structure: audio/x-raw, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ];
0:00:00.099085743 13567 0x7fd40c004600 INFO GST_ELEMENT_PADS gstelement.c:1013:gst_element_get_static_pad: no such pad 'src_%u' in element "decodebin"
0:00:00.099126988 13567 0x7fd40c004600 INFO GST_ELEMENT_PADS gstutils.c:1270:gst_element_get_compatible_pad:<decodebin> Could not find a compatible pad to link to audioconvert:sink
The decodebin source pad is a dynamic pad so it's not available right at the creation of the element. I confirmed it by running the request_pad method which returned None. So I tried to delete the line where I linked the elements then added an action on the event pad_added like shown in the documentation in order to directly link the pads. However my lambda is never called. Here's the line I used:
decodebin.connect("pad_added", true, |value| { info!("new pad {:?}", value); None });
I'm not sure if I'm listening to the event correctly. The only examples I found were in C. Either that or there's another issue...
EDIT: After a good sleep I just found an example where instead it uses the connect_pad_added method. I'll test this later but I think it's the solution.
Ok so I replaced this line:
gst::Element::link(&decodebin, &audioconvert).expect("Could not link decodebin and audioconvert");
into:
let audioconvert_weak = audioconvert.downgrade();
decodebin.connect_pad_added(move |_, src_pad| {
println!("new pad {:?}", src_pad);
let sink_pad = match audioconvert_weak.upgrade() {
None => return,
Some(s) => s.static_pad("sink").expect("cannot get sink pad from sink")
};
src_pad.link(&sink_pad).expect("Cannot link the decodebin source pad to the audioconvert sink pad");
});
Instead of linking the 2 elements I set a closure which is called when a pad is added for the decodebin element. The code in the closure will then print a message, get the sink pad from my audioconvert element (that I passed using a weak reference) and finally link the pads.
Let's assume I have an actor class with a method in Akka Actor:
class SecureActor extends Actor{
def methodWithThread(): Unit={
}
Can a run a new thread in this method? Wouldn't it be problematic regarding Akka's own threading?
class ThreadExample extends Thread{
override def run(){
println("Thread is running...");
}
def methodWithThread(): Unit={
var t = new ThreadExample()
t.start()
}
Since you said that you are looking for how to make sure that this way that you want to create async tasks from an Akka Actor will break the Akka concurrency pattern that it provides to you, here is some very simple example based on your classes.
This is not an answer to demonstrate how to spawn child actors from a parent actor as I suggested in my commentary. And as you also said that you are interested to demonstrate how to break the Akka concurrency pattern. I suggested that you look for simple examples of how to do that. Maybe this example helps.
import akka.actor.{Actor, ActorSystem, Props}
import scala.util.Random
object BreakingAkkaConcurrency {
def main(args: Array[String]): Unit = {
val actorSystem = ActorSystem("BreakingAkkaConcurrency")
val unsecureActor = actorSystem.actorOf(Props[UnsecureActor], "unsecureActor")
unsecureActor ! "1"
unsecureActor ! "2"
unsecureActor ! "3"
unsecureActor ! "4"
unsecureActor ! "5"
unsecureActor ! "6"
unsecureActor ! "7"
unsecureActor ! "8"
unsecureActor ! "9"
unsecureActor ! "10"
Thread.sleep(10000)
}
}
class UnsecureActor extends Actor {
def methodWithThread(): Unit = {
}
override def receive: Receive = {
case msg: String =>
var t = new ThreadExample(msg)
// by starting a new thread inside an Akka actor you break the synchronous pattern provided by Akka
t.start()
}
}
class ThreadExample(id: String) extends Thread {
override def run() {
// simulate a random computation which will potentially break the order of messages processed by Akka actors
// This is where the Akka actors don't have control anymore.
Thread.sleep(Random.nextInt(10) * 1000)
println(s"finished $id");
}
}
the output will be in a different order than the unsecureActor ! "1" send messages.
finished 9
finished 4
finished 1
finished 7
finished 3
finished 2
finished 8
finished 5
finished 6
finished 10
It is OK to start code in a separate thread from inside an Actor (e.g. using Future) but you have to be careful about how it interacts with Akka. The thread should not read or modify any mutable state in the Actor, and it should only communicate with the Actor by sending messages.
Using Java Gstreamer binding 1, I want to read an audio file from disk and write a segment of this file back to disk. For this, I cannot use the "filesrc" element, but instead I found that I can use the "gnlurisource" element from the Gnonlin plugin 2.
I took Gstreamer Java binding and I compiled it locally, getting a jar file that I added to my project. I also installed Gstreamer on Ubuntu using the following commands:
sudo apt-get install libgstreamer1.0-dev
sudo apt-get install gstreamer1.0-gnonlin
The program compiles without errors, but it remains stuck and does nothing. Below I attach my program code:
import java.util.concurrent.TimeUnit;
import org.freedesktop.gstreamer.Element;
import org.freedesktop.gstreamer.ElementFactory;
import org.freedesktop.gstreamer.Gst;
import org.freedesktop.gstreamer.Pipeline;
import org.freedesktop.gstreamer.State;
public class AudioSegmentation {
public static void main(String[] args) {
Pipeline pipe;
Element asr;
Element composition;
Element gnlsource;
Element convert;
Element filesink;
Gst.init();
pipe = new Pipeline("SimplePipeline");
composition = ElementFactory.make("gnlcomposition", "comp");
gnlsource = ElementFactory.make("gnlurisource", "gnlsource");
convert = ElementFactory.make("audioconvert", "compconvert");
filesink = ElementFactory.make("filesink", "filesink");
gnlsource.set("uri", "file:///home/user/Desktop/file-source.wav");
gnlsource.set("start", TimeUnit.SECONDS.toNanos(5));
gnlsource.set("duration", TimeUnit.SECONDS.toNanos(2));
filesink.set("location", "/home/user/Desktop/file-destination.wav");
composition.link(gnlsource);
pipe.addMany(composition, convert, filesink);
Element.linkMany(composition, convert, filesink);
pipe.setState(State.PLAYING);
Gst.main();
Gst.quit();
}
}
I don't have so much experience with Gstreamer, can you give me a hint about what's wrong?
Thank you!
UPDATE: I managed to use gstreamer from the command line to select a segment from an audio file. The "gnlurisource" element has the "inpoint" paramenter to set the segment start time and "duration" to specify the duration of the segment.
Here is the command:
gst-launch-1.0 gnlurisource uri=file:///home/user/Desktop/file-source.wav inpoint=2000000000 duration=1500000000 ! audioconvert ! wavenc ! filesink location=/home/user/Desktop/file-destination.wav
I'm still trying to implement this pipeline in Java. I tried something like that, but it doesn't work:
import java.util.concurrent.TimeUnit;
import org.freedesktop.gstreamer.Element;
import org.freedesktop.gstreamer.ElementFactory;
import org.freedesktop.gstreamer.Gst;
import org.freedesktop.gstreamer.Pipeline;
import org.freedesktop.gstreamer.State;
public class AudioSegmentation {
public static void main(String[] args) {
Pipeline pipe;
Element gnlsource;
Element audioconvert;
Element wavenc;
Element filesink;
Gst.init();
pipe = new Pipeline("SimplePipeline");
gnlurisource = ElementFactory.make("gnlurisource", "gnlurisource");
audioconvert = ElementFactory.make("audioconvert", "audioconvert");
wavenc = ElementFactory.make("wavenc", "wavenc");
filesink = ElementFactory.make("filesink", "filesink");
gnlurisource.set("uri", "file:///home/user/Desktop/file-source.wav");
gnlurisource.set("inpoint", TimeUnit.SECONDS.toNanos(2));
gnlurisource.set("duration", TimeUnit.SECONDS.toNanos(3));
filesink.set("location", "/home/user/Desktop/file-destination.wav");
pipe.addMany(gnlurisource, audioconvert, wavenc, filesink);
Element.linkMany(gnlurisource, audioconvert, wavenc, filesink);
pipe.setState(State.PLAYING);
Gst.main();
Gst.quit();
}
I tried the samples given in github griffon-master, also I tried the samples of the guide.
I would like to use javafx and groovy.
I would like to use fxml - thought of a scenario as that: fxml to set the stage, and for changes, use the groovy (set adjustment)
It seems that is not possible. I can use ("make it run"): javafx-java, read an fxml (with loadFromFXML), and the bindings are working. If using javafx-groovy, I can read an fxml, but with the javafx-class Loader (load), and bindings are not working (or it seems so).
Is it not possible at this moment, to use javafx-groovy and read-in fxml (via loadfromfxml)?
Could you post some sample code? Here's one example that makes use of the fxml node form GroovyFX
package org.example
import griffon.core.artifact.GriffonView
import griffon.metadata.ArtifactProviderFor
import javafx.scene.control.Tab
import org.codehaus.griffon.runtime.javafx.artifact.AbstractJavaFXGriffonView
#ArtifactProviderFor(GriffonView)
class Tab4View extends AbstractJavaFXGriffonView {
FactoryBuilderSupport builder
SampleController controller
SampleModel model
private AppView parentView
void initUI() {
builder.with {
content = builder.fxml(resource('/org/example/tab4.fxml')) {
inputLabel.text = application.messageSource.getMessage('name.label')
bean(input, text: bind(model.inputProperty()))
bean(output, text: bind(model.outputProperty()))
}
}
connectActions(builder.content, controller)
Tab tab = new Tab('Hybrid')
tab.content = builder.content
parentView.tabPane.tabs.add(tab)
}
}
This can be done. The trick is to make your Controller actions adhere to a stringent set of rules. The tldr is to make sure they return void.
Good:
def void save() {
Bad:
def save() {
The reason is found in the reflective analysis the Griffon framework uses to create its list of action targets. This list is generated in DefaultGriffonControllerClass.getActionNames(), which requires that:
Actions are subject to the following rules in order to be considered as such:
must have public (Java) or default (Groovy) visibility modifier.
name does not match an event handler, i.e, it does not begin with on.
must pass {code GriffonClassUtils.isPlainMethod()} if it's a method.
must have void as return type if it's a method.
value must be a closure (including curried method pointers) if it's a property.
The criteria defined in GriffonClassUtils.isPlainMethod() are as follows:
isInstanceMethod(method)
! isBasicMethod(method)
! isGroovyInjectedMethod(method)
! isThreadingMethod(method)
! isArtifactMethod(method)
! isMvcMethod(method)
! isServiceMethod(method)
! isEventPublisherMethod(method)
! isObservableMethod(method)
! isResourceHandlerMethod(method)
! isGetterMethod(method)
! isSetterMethod(method)
! isContributionMethod(method)
The list of action target names is subsequently used by AbstractActionManager:
#Nullable
private static Method findActionAsMethod(#Nonnull GriffonController controller, #Nonnull String actionName) {
for (Method method : controller.getClass().getMethods()) {
if (actionName.equals(method.getName()) &&
isPublic(method.getModifiers()) &&
!isStatic(method.getModifiers()) &&
method.getReturnType() == Void.TYPE) {
return method;
}
}
return null;
}