Streaming Desktop in VLCJ - java

I'm trying to write a Java program which allows one user to act as a server and stream their desktop (video & audio), then other users act as clients and watch the live stream of their desktop (similar to Twitch, Webex, Skype screenshare, etc). I am using VLCJ for this, although I have no commitment to using it so if there is a better solution I'm all ears. Here is the code, which is copied from the link I provide below:
package test.java;
import uk.co.caprica.vlcj.discovery.NativeDiscovery;
import uk.co.caprica.vlcj.player.MediaPlayerFactory;
import uk.co.caprica.vlcj.player.headless.HeadlessMediaPlayer;
import test.java.VlcjTest;
/**
* An example of how to stream a media file over HTTP.
* <p>
* The client specifies an MRL of <code>http://127.0.0.1:5555</code>
*/
public class StreamHttp extends VlcjTest {
//when running this it requires an MRL (Media Resource Locator)
//fancy term for saying the file you want to stream. This could be a url to another
//location that streams media or a filepath to a media file you want to stream
//on the system you are running this code on.
public static void main(String[] args) throws Exception {
new NativeDiscovery().discover();
if(args.length != 1) {
System.out.println("Specify a single MRL to stream");
System.exit(1);
}
//the media you are wanting to stream
String media = args[0];
//this is the IP address and port you are wanting to stream at
//this means clients will connect to http://127.0.0.1:5555
//to watch the stream
String options = formatHttpStream("127.0.0.1", 5555);
System.out.println("Streaming '" + media + "' to '" + options + "'");
//this creates a the actual media player that will make calls into the native
//vlc libraries to actually play the media you supplied. It does it in
//a headless fashion, as you are going to stream it over http to be watched
//instead of playing it locally to be watched.
MediaPlayerFactory mediaPlayerFactory = new MediaPlayerFactory(args);
HeadlessMediaPlayer mediaPlayer = mediaPlayerFactory.newHeadlessMediaPlayer();
//this simply starts the player playing the media you gave it
mediaPlayer.playMedia(media, options);
// Don't exit
//basically you don't want the thread to end and kill the player,
//so it just hangs around and waits for it to end.
Thread.currentThread().join();
}
private static String formatHttpStream(String serverAddress, int serverPort) {
StringBuilder sb = new StringBuilder(60);
sb.append(":sout=#duplicate{dst=std{access=http,mux=ts,");
sb.append("dst=");
sb.append(serverAddress);
sb.append(':');
sb.append(serverPort);
sb.append("}}");
return sb.toString();
}
}
I pass "screen://" as a parameter to this program. When I run the code, I get this error message:
[000000000038b250] access_output_http access out: Consider passing --http-host=IP on the command line instead.
[000000001ccaa220] core mux error: cannot add this stream
[000000001cc72100] core decoder error: cannot create packetizer output (RV32)
I tried searching for a solution but all I could find was this:
Video Streaming in vlcj
and although this user had the same error, I couldn't solve my problem from this link, although I did use the StreamHttp code sample from it. I am a relatively inexperienced programmer so if I missed an obvious solution then I apologize. I am using Java 1.8, Windows 7 64 bit.

You need something like this:
String media = "screen://";
String[] options = {
":sout=#transcode{vcodec=FLV1,vb=4096,scale=0.500000}:http{mux=ffmpeg{mux=flv},dst=:5000/"
};
The key things shown here are a "sout" string to transcode the video, then another appended "sout" string to stream (in this case via http).
In this example string, for http streaming only the port (5000, arbitrarily chosen) is specified. No host is specified, so it means localhost. You could have something like "dst=127.0.0.1:8080/" or whatever you need.
You will have to choose/experiment with the specific transcoding/streaming options that you want. There is no one size fits all for those options.
Foot-note:
You can actually use VLC itself to generate this string for you.
Start VLC, then choose the media you want to play.
Instead of pressing "Play", use the widget to select "Stream" instead. This opens the Streaming wizard where you can pick all of your options.
At the end of the wizard, before you start playing, it shows you the string you need.

Related

How do I pass multiple types of data over a serial port connection using JSSC?

I am tasked with creating a program that can initiate a payment on an Ingenico card terminal. It is a smaller part to a larger project to create a custom P.O.S system for a business. But I am facing a variety of road blocks making this problem difficult.
I have no experience in programming with serial ports. The documentation I have found online only depicts writing strings or bytes. The examples are simple but do not tell me enough information.
There is no documentation for the device I am using. Ingenico does not provide this information. The only way I have been able to figure out what data the card reader is expecting to initiate a payment is via this already completed project on github. Here is the link
https://github.com/Ousret/pyTeliumManager
This implementation is in python, and is using a linux-based system. We would be using this but we need a more custom implementation, hence why I am doing this in java.
I have looked and looked in this project to find how the data is structured and then sent over the serial port connection, but at this point I am missing it out of ignorance. I'm not familiar with python at all and the only thing I know is that the data to initiate a payment is as follows...
a float for the transaction amount
three strings, one for the currency type (USD, EUR etc) payment method (card) and the checkout ID (which can be anything, this is for personal book keeping)
and three booleans, one if you would like to wait for the transaction to be approved, one if you would like bank verification and one if you would like the payees payment information saved. (Ive set all these to false as they're not necessary at this moment. I am just trying to write something that works as a proof of concept before building an interface)
Now, here's some of my test code, and most of this is similar to what I've found on the internet through my research.
public static void main(String[] args) {
SerialPort cerealPort = new SerialPort("COM9");
try {
System.out.println("Port opened: " + cerealPort.openPort());
System.out.println("reading bytes " + cerealPort.readBytes());
System.out.println("name " + cerealPort.getPortName());
cerealPort.writeString("bing bong");
//cerealPort.setEventsMask(256);
System.out.println("Params setted: " + cerealPort.setParams(9600, 8, 1, 0));
System.out.println("\"Hello World!!!\" successfully writen to port: " + cerealPort.writeBytes("Hello World!!!".getBytes()));
System.out.println("Port closed: " + cerealPort.closePort());
}
catch (SerialPortException ex){
System.out.println(ex);
}
}
}
This code really doesn't really do anything and was just to test that communication with the device is working properly. Note that nothing happens on the terminal when this code is run.
Now I have this class called TelliumData, which has the data members I described.
public class TelliumData {
float amount;
String paymentMode = "debit";
String currency = "USD";
String checkoutId = "1";
boolean transactionWait = false; // waits for trans to end. Set to True if you need valid transaction status otherwise, set it to False.
boolean collectPaymentInfo = false;
boolean forceBankVerify = false;
}
I have 0 idea how to pass this information to the terminal using the functions in JSSC
My question is, at its core, how to I send this data over a serial port?
I have tried using .writebytes and .writeint to send over all data one by one but this doesn't do anything and doesn't trigger a payment initialization on the card reader.
I don't understand how the python implementation has done it either. It would be great if someone could explain how that data is packaged and sent.

Example on how to use TFileTransport in Thrift (Client/Server)

Is there anyone who managed to get TFileTransport as a transport layer, to work? I've tried but since there is no documentation (or have I not found it?) for this, I am not able to make it work.
If anyone have been more successful and could provide some sample code, it would be great.
edit:
What I've tried so far:
public class FileThriftServer {
public static void startThriftServer(
ThriftDataBenchmark.Processor<ThriftDataBenchmarkHandler> processor) {
try {
File input = new File("ThriftFile.in");
if(!input.exists()){
input.createNewFile();
}
File output = new File("ThriftFile.out");
if(!output.exists()){
output.createNewFile();
}
TFileTransport inputFileTransport = new TFileTransport(input.getAbsolutePath(), true);
TFileTransport outputFileTransport = new TFileTransport(output.getAbsolutePath(), false);
inputFileTransport.open();
outputFileTransport.open();
TFileProcessor fProcessor =
new TFileProcessor(processor, new TJSONProtocol.Factory(), inputFileTransport, outputFileTransport);
// this results in error in case I don't call those open methods above
fProcessor.processChunk();
System.out.println("File Thrift service started ...");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// ThriftDataBenchmarkHandler is an implementation of my test service
startThriftServer(new ThriftDataBenchmark.Processor<ThriftDataBenchmarkHandler>(
new ThriftDataBenchmarkHandler()));
}
}
Now I don't know if I am even on a good way, maybe I misunderstood the concept of this transport (again, it is not documented). I would expect I start the server by some method now which will listen on the input file. When clients put there something, it would process it and write the answer to output file (I didn't try to write client yet since this peace of code just executes and exists, it is obviously not right).
edit 2:
Ok, so if I understand it right, this code is ok and it should process one request of the client, if it's there. So I am moving to the client side, doing something like this:
File input = new File(THRIFT_INPUT_FILE_PATH);
if (!input.exists()) {
input.createNewFile();
}
TTransport transport = new TFileTransport(input.getAbsolutePath(),
false);
TProtocol protocol = new TJSONProtocol(transport);
ThriftDataBenchmark.Client client = new ThriftDataBenchmark.Client(
protocol);
// my testing service, the parameters are not important
SimpleCompany company = client.getSimpleCompanyData("token", 42);
Unfortunatelly calling getSimpleCompanyData results in:
org.apache.thrift.transport.TTransportException: Not Supported
at org.apache.thrift.transport.TFileTransport.write(TFileTransport.java:572)
at org.apache.thrift.transport.TTransport.write(TTransport.java:105)
at org.apache.thrift.protocol.TJSONProtocol.writeJSONArrayStart(TJSONProtocol.java:476)
at org.apache.thrift.protocol.TJSONProtocol.writeMessageBegin(TJSONProtocol.java:487)
at org.apache.thrift.TServiceClient.sendBase(TServiceClient.java:62)
It's a bit confusing that server side requires input and output transport but on the client side, it only accepts one. How does it read an answer and from where?
Let's not move into some extra logic of checking the file for changes, if it's not already part of Thrift. I'll be ok at this point by doing it manually in sense of: running the client first, then running the server side.
I would expect I start the server by some method now which will listen on the input file. When clients put there something, it would process it and write the answer to output file (I didn't try to write client yet since this peace of code just executes and exists, it is obviously not right).
That's exactly right. In particular, the fProcessor.processChunk() call you used will process exactly one chunk (the current one). The whole class looks as designed around the assumption that the file size is static and does not change over time. However, the underlying TFileTransport supports what's called a tailPolicy, used when a read call hits EOF:
public class TFileTransport extends TTransport {
public static enum tailPolicy {
NOWAIT(0, 0),
WAIT_FOREVER(500, -1);
/**
* Time in milliseconds to sleep before next read
* If 0, no sleep
*/
public final int timeout_;
/**
* Number of retries before giving up
* if 0, no retries
* if -1, retry forever
*/
public final int retries_;
// ... ctor ...
}
/**
* Current tailing policy
*/
tailPolicy currentPolicy_ = tailPolicy.NOWAIT;
Another option to get it to work could be calling fProcessor.processChunk(int chunkNum), watching the file contents separately and repeat the calls when new data come in. It's certainly not such a bad idea to use the TFileProcessor as a starting point and improve it as needed.
// this results in error in case I don't call those open methods above
fProcessor.processChunk();
Opening the transports before using is fine. I think that part is ok.
org.apache.thrift.transport.TTransportException: Not Supported
at org.apache.thrift.transport.TFileTransport.write(TFileTransport.java:572)
at org.apache.thrift.transport.TTransport.write(TTransport.java:105)
Unfortunately, that seems pretty correct yet. The only place where writing is implemented is the code in the C++ library. Both Java and D only support reading (yet).

Java -how can I open URL and insert the URL user and password?

I want to learn how to:
Step1: open URL – for example Gmail
Step 2: insert user and password and press sign-in.
How can I inset user and password and press the sign-in button?
Do I need/must use selenium?
This code is only for open the browser(step 1)
import java.io.IOException;
public class Website
{
public void openWebsite() //throws IOException
{
try
{
#SuppressWarnings("unused")
Process p = Runtime.getRuntime().exec("cmd /c start http://accounts.google.com/ServiceLogin ");
}
catch (IOException e1)
{
System.out.println(e1);
}
}
}
First you need to open the URL. Right now you are actually not opening the URL. You are asking the Windows operating system "What would you do with http://accounts.google.com/ServiceLogin?"
Because it is windows, it will make a guess, which sort of follows this line of logic:
it sort of looks like a URL, so I'll fire up explorer and
ask explorer to do something with it.
Which means that your code is now a few programs away from being able to get the data, and none of the intermediate programs will (because they're not built to do so), transmit the need for input into your program.
What you need to do is to avoid asking other programs to open the URL, it's just too problematic. First, they might get it wrong, second they'll never know how to ask you the input. To open a URL directly:
import java.net.URL;
... somewhere in the code ...
URL url = new URL("http://accounts.google.com/ServiceLogin");
InputStream in = url.openStream();
do some googling on various java.net.URL tutorials, and you will soon find the right combination of techniques needed to handle your particular credential challenge. Here's one resource, but it seems you need to do a bit of homework before what they say will make sense to you. If you stumble, at least you'll have a better, more specific question to ask the next time around (and don't forget to post your source code).

Detect mobile devices from user agent string [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 4 years ago.
Improve this question
I am looking for a way to analyze user agent strings to determine whether they were generated by mobile devices. This needs to be java-based and usable in large batch log file analysis on hadoop for generating statistics (i.e., a web service wouldn't be appropriate).
I have seen WURFL, but given that I just need a binary mobile/not mobile response, the license fee seems prohibitive.
So far I have been using UADetector, which is almost exactly what I need. However, I have encountered some limitations with it. In my testing, I have found many user agent strings that provide enough information to determine that the user agent is from a mobile device, but are reported as UNKNOWN by UADetector.
For example, poorly-standardized Android apps can send the UA string "Android". This is enough to know that it came from a mobile device, but UADetector reports this UserAgentType as UNKNOWN rather than MOBILE_BROWSER.
Apache Mobile Filter's Lite Device Detection does the right thing, but I need something I can use from Java.
Can anyone recommend a better solution?
I'm the founder and maintainer of the MobileESP project, a free open source cross-platform library for detecting mobile devices. It's still very much alive! :-)
www.mobileesp.org
MobileESP only gives binary "is mobile" responses. You can detect by platform like iOS, Android or Windows Phone, or by device category, like "iPhone Tier" smartphones vs. tablet. Be sure to take a quick review of the API page.
As you may know, useragent strings vary widely. If the browser shipped on the device, the manufacturer may customize it. For example, HTC often customizes the native Android browser's useragent string.
Google provides recommendations on how the OEM should customize the useragent. If the device should be considered a phone, then Google recommends including the word "mobile" element in the string. But if the device should be considered a tablet, then the string should not contain "mobile." Adherence to this recommendation varies widely, of course.
Third party browsers like Opera or Maxthon can put whatever they want to in the useragent string -- and do! Certain "new" browsers which shall remain nameless have been doing very poor jobs of putting the correct information in their useragent strings for each platform (e.g., Android vs. iOS versions). There's not much you can do unless you get a lot of traffic from these browsers and wish to invest in tracking their exact useragent values per platform and software rev.
Anyway, MobileESP was created with the vision of doing the detection on a page-by-page basis when the page is served. I purposefully wrote the code to be very easy to read and customize, too.
To do the batch processing, you might do something like this:
1.) In the constructor, comment out the initDeviceScan() method. You won't need this for bulk processing.
2.) Pass the UserAgent and an empty string in to the constructor (UAgentInfo()).
3.) Then run whatever detect methods you're interested in. Be thoughtful about the order in which you do them to save time, based on a scan of your users.
For example, if most of your users are on iPhone and that's one of the detection criteria you're interested in, then run that check first. If this example, you certainly wouldn't run the BlackBerry method first!
My contact info is in the source code and on the web site. Send me a note if you have any questions or run into any bugs. Definitely look around the MobileESP.org web site for some tips.
Best wishes on your project, Aniket!
Anthony
Another thread suggests using the following library:
https://github.com/ahand/mobileesp/blob/master/Java/UAgentInfo.java
which seems OK.
How to read the Apache Mobile Filter value in JSP (for Tomcat)?
Before in the httpd.conf file where you have to configure mod_jk you muse add this:
JkEnvVar AMF_IS_MOBILE undefined
The Java code is:
request.getAttribute("AMF_IS_MOBILE")
from: http://wiki.apachemobilefilter.org
51Degrees has a free open source Java API that allows you to run offline processing. You can access it from the GitHub Repository here. https://github.com/51Degrees/Java-Device-Detection.
As part of the API there is an offline processing example (code also shown below) this takes a CSV file of User-Agents and returns the required properties into an Output file. The following example just uses 3 of the properties within the data set, for a full list you can look at the dictionary here https://51degrees.com/resources/property-dictionary
// output file in current working directory
public String outputFilePath = "batch-processing-example-results.csv";
// pattern detection matching provider
private final Provider provider;
/**
* Initialises the device detection Provider with the included Lite data
* file. For more data see:
* <a href="https://51degrees.com/compare-data-options">compare data options
* </a>
*
* #throws IOException if there was a problem reading from the data file.
*/
public OfflineProcessingExample() throws IOException {
provider = new Provider(StreamFactory.create(
Shared.getLitePatternV32(), false));
}
/**
* Reads a CSV file containing User-Agents and adds the IsMobile,
* PlatformName and PlatformVersion information for the first 20 lines.
* For a full list of properties and the files they are available in please
* see: <a href="https://51degrees.com/resources/property-dictionary">
* Property Dictionary</a>
*
* #param inputFileName the CSV file to read from.
* #param outputFilename where to save the file with extra entries.
* #throws IOException if there was a problem reading from the data file.
*/
public void processCsv(String inputFileName, String outputFilename)
throws IOException {
BufferedReader bufferedReader =
new BufferedReader(new FileReader(inputFileName));
try {
FileWriter fileWriter = new FileWriter(outputFilename);
try {
// it's more efficient over the long haul to create a match
// once and reuse it in multiple matches
Match match = provider.createMatch();
// there are 20k lines in supplied file, we'll just do a couple
// of them!
for (int i = 0; i < 20; i++) {
// read next line
String userAgentString = bufferedReader.readLine();
// ask the provider to match the UA using match we created
provider.match(userAgentString, match);
// get some property values from the match
Values isMobile = match.getValues("IsMobile");
Values platformName = match.getValues("PlatformName");
Values platformVersion = match.getValues("PlatformVersion");
// write result to file
fileWriter.append("\"")
.append(userAgentString)
.append("\", ")
.append(getValueForDisplay(isMobile))
.append(", ")
.append(getValueForDisplay(platformName))
.append(", ")
.append(getValueForDisplay(platformVersion))
.append('\n')
.flush();
}
} finally {
fileWriter.close();
}
} finally {
bufferedReader.close();
}
}
/**
* Match values may be null. A helper method to get something displayable
* #param values a Values to render
* #return a non-null String
*/
protected String getValueForDisplay(Values values) {
return values == null ? "N/A": values.toString();
}
/**
* Closes the {#link fiftyone.mobile.detection.Dataset} by releasing data
* file readers and freeing the data file from locks. This method should
* only be used when the {#code Dataset} is no longer required, i.e. when
* device detection functionality is no longer required, or the data file
* needs to be freed.
*
* #throws IOException if there was a problem accessing the data file.
*/
#Override
public void close() throws IOException {
provider.dataSet.close();
}
/**
* Instantiates this class and starts
* {#link #processCsv(java.lang.String, java.lang.String)} with default
* parameters.
*
* #param args command line arguments.
* #throws IOException if there was a problem accessing the data file.
*/
public static void main(String[] args) throws IOException {
System.out.println("Starting Offline Processing Example");
OfflineProcessingExample offlineProcessingExample =
new OfflineProcessingExample();
try {
offlineProcessingExample.processCsv(Shared.getGoodUserAgentsFile(),
offlineProcessingExample.outputFilePath);
System.out.println("Output written to " +
offlineProcessingExample.outputFilePath);
} finally {
offlineProcessingExample.close();
}
}
Hope this helps.
Disclosure: I work at 51Degrees.
To detect iPhone, Android and other mobile devices in Java user-agent can be used. If you are using Spring you can customize the below code as per your need.
#Override
public ModelAndView redirectToAppstore(HttpServletRequest request) {
String userAgent = request.getHeader("user-agent").toLowerCase();
String iphoneStoreUrl = "IPONE_STORE_URL";
String androidStoreUrl = "ANDROID_STORE_URL";
if (userAgent.contains("iphone"))
return new ModelAndView("redirect:" + iphoneStoreUrl);
else if (userAgent.contains("android"))
return new ModelAndView("redirect:" + androidStoreUrl);
return new ModelAndView("redirect:/");
}

Download Pandora source with Java?

I'm trying to download www.pandora.com/profile/stations/olin_d_kirkland HTML with Java to match what I get when I select 'view page source' from the context menu of the webpage in Chrome.
Now, I know how to download webpage HTML source code with Java. I have done it with downloads.nl and tested it on other sites. However, Pandora is being a mystery. My ultimate goal is to parse the 'Stations' from a Pandora account.
Specifically, I would like to grab the Station names from a site such as www.pandora.com/profile/stations/olin_d_kirkland
I have attempted using the selenium library and the built in URL getter in Java, but I only get ~4700 lines of code when I should be getting 5300. Not to mention that there is no personalized data in the code, which is what I'm looking for.
I figured it was that I wasn't grabbing the JavaScript or letting the JavaScript execute first, but even though I waited for it to load in my code, I would only always get the same result.
If at all possible, I should have a method called 'grabPageSource()' that returns a String. It should return the source code when called upon.
public class PandoraStationFinder {
public static void main(String[] args) throws IOException, InterruptedException {
String s = grabPageSource();
String[] lines = s.split("\n\r");
String t;
ArrayList stations = new ArrayList();
for (int i = 0; i < lines.length; i++) {
t = lines[i].trim();
Pattern p = Pattern.compile("[\\w\\s]+");
Matcher m = p.matcher(t);
if (m.matches() ? true : false) {
Station someStation = new Station(t);
stations.add(someStation);
// System.out.println("I found a match on line " + i + ".");
// System.out.println(t);
}
}
}
public static String grabPageSource() throws IOException {
String fullTxt = "";
// Get HTML from www.pandora.com/profile/stations/olin_d_kirkland
return fullTxt;
}
}
It is irrelevant how it's done, but I'd like, in the final product, to grab a comprehensive list of ALL songs that have been liked by a user on Pandora.
The Pandora pages are heavily constructed using ajax, so many scrapers struggle. In the case you've shown above, looking at the list of stations, the page actually puts through a secondary request to:
http://www.pandora.com/content/stations?startIndex=0&webname=olin_d_kirkland
If you run your request, but point it to that URL rather than the main site, I think you will have a lot more luck with your scraping.
Similarly, to access the "likes", you want this URL:
http://www.pandora.com/content/tracklikes?likeStartIndex=0&thumbStartIndex=0&webname=olin_d_kirkland
This will pull back the liked tracks in groups of 5, but you can page through the results by increasing the 'thumbStartIndex' parameter.
Not an answer exactly, but hopefully this will get you moving in the correct direction:
Whenever I get into this sort of thing, I always fall back on an HTTP monitoring tool. I use firefox, and I really like the Live HTTP Headers extension. Check out what the headers are that are going back and forth, then tailor your http requests accordingly. As an absolute lowest level test, grab the header from a successful request, then send it to port 80 using telnet and see what comes back.

Categories

Resources