I want to access a youtube video and play using my own media player. I am able to get the video properties (title, url etc..) using the youtube data API. Can I get access to the stream of the video and use my own Media Player (like the Android Media Player) to play it.
I am trying all of these in JAVA.
Thanks in advance.. :)
/**
* This work is licensed under a Creative Commons Attribution 3.0 Unported
* License (http://creativecommons.org/licenses/by/3.0/). This work is placed
* into the public domain by the author.
*/
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.client.utils.URIUtils;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
/**
* Locally download a YouTube.com video.
*/
public class JavaYoutubeDownloader extends Formatter {
private static final String scheme = "http";
private static final String host = "www.youtube.com";
private static final String YOUTUBE_WATCH_URL_PREFIX = scheme + "://" + host + "/watch?v=";
private static final String ERROR_MISSING_VIDEO_ID = "Missing video id. Extract from " + YOUTUBE_WATCH_URL_PREFIX + "VIDEO_ID";
private static final String DEFAULT_USER_AGENT = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13";
private static final String DEFAULT_ENCODING = "UTF-8";
private static final String newline = System.getProperty("line.separator");
private static final Logger log = Logger.getLogger(JavaYoutubeDownloader.class.getCanonicalName());
private static final Logger rootlog = Logger.getLogger("");
private static final Pattern commaPattern = Pattern.compile(",");
private static final Pattern pipePattern = Pattern.compile("\\|");
private static final char[] ILLEGAL_FILENAME_CHARACTERS = { '/', '\n', '\r', '\t', '\0', '\f', '`', '?', '*', '\\', '<', '>', '|', '\"', ':' };
private static final int BUFFER_SIZE = 2048;
private static final DecimalFormat commaFormatNoPrecision = new DecimalFormat("###,###");
private static final double ONE_HUNDRED = 100;
private static final double KB = 1024;
private void usage(String error) {
if (error != null) {
System.err.println("Error: " + error);
}
System.err.println("usage: JavaYoutubeDownload VIDEO_ID");
System.err.println();
System.err.println("Options:");
System.err.println("\t[-dir DESTINATION_DIR] - Specify output directory.");
System.err.println("\t[-format FORMAT] - Format number" + newline + "\t\tSee http://en.wikipedia.org/wiki/YouTube#Quality_and_codecs");
System.err.println("\t[-ua USER_AGENT] - Emulate a browser user agent.");
System.err.println("\t[-enc ENCODING] - Default character encoding.");
System.err.println("\t[-verbose] - Verbose logging for downloader component.");
System.err.println("\t[-verboseall] - Verbose logging for all components (e.g. HttpClient).");
System.exit(-1);
}
public static void main(String[] args) {
try {
new JavaYoutubeDownloader().run(args);
} catch (Throwable t) {
t.printStackTrace();
}
}
private void run(String[] args) throws Throwable {
setupLogging(Level.WARNING, Level.WARNING);
String videoId = null;
String outdir = ".";
int format = 18;
String encoding = DEFAULT_ENCODING;
String userAgent = DEFAULT_USER_AGENT;
for (int i = 0; i < args.length; i++) {
String arg = args[i];
// Options start with either -, --
// Do not accept Windows-style args that start with / because of abs
// paths on linux for file names.
if (arg.charAt(0) == '-') {
// For easier processing, convert any double dashes to
// single dashes
if (arg.length() > 1 && arg.charAt(1) == '-') {
arg = arg.substring(1);
}
String larg = arg.toLowerCase();
// Process the option
if (larg.equals("-help") || larg.equals("-?") || larg.equals("-usage") || larg.equals("-h")) {
usage(null);
} else if (larg.equals("-verbose")) {
setupLogging(Level.ALL, Level.WARNING);
} else if (larg.equals("-verboseall")) {
setupLogging(Level.ALL, Level.ALL);
} else if (larg.equals("-dir")) {
outdir = args[++i];
} else if (larg.equals("-format")) {
format = Integer.parseInt(args[++i]);
} else if (larg.equals("-ua")) {
userAgent = args[++i];
} else if (larg.equals("-enc")) {
encoding = args[++i];
} else {
usage("Unknown command line option " + args[i]);
}
} else {
// Non-option (i.e. does not start with -, --
videoId = arg;
// Break if only the first non-option should be used.
break;
}
}
if (videoId == null) {
usage(ERROR_MISSING_VIDEO_ID);
}
log.fine("Starting");
if (videoId.startsWith(YOUTUBE_WATCH_URL_PREFIX)) {
videoId = videoId.substring(YOUTUBE_WATCH_URL_PREFIX.length());
}
int a = videoId.indexOf('&');
if (a != -1) {
videoId = videoId.substring(0, a);
}
File outputDir = new File(outdir);
String extension = getExtension(format);
play(videoId, format, encoding, userAgent, outputDir, extension);
log.fine("Finished");
}
private static String getExtension(int format) {
switch (format) {
case 18:
return "mp4";
default:
throw new Error("Unsupported format " + format);
}
}
private static void play(String videoId, int format, String encoding, String userAgent, File outputdir, String extension) throws Throwable {
log.fine("Retrieving " + videoId);
List<NameValuePair> qparams = new ArrayList<NameValuePair>();
qparams.add(new BasicNameValuePair("video_id", videoId));
qparams.add(new BasicNameValuePair("fmt", "" + format));
URI uri = getUri("get_video_info", qparams);
CookieStore cookieStore = new BasicCookieStore();
HttpContext localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(uri);
if (userAgent != null && userAgent.length() > 0) {
httpget.setHeader("User-Agent", userAgent);
}
log.finer("Executing " + uri);
HttpResponse response = httpclient.execute(httpget, localContext);
HttpEntity entity = response.getEntity();
if (entity != null && response.getStatusLine().getStatusCode() == 200) {
InputStream instream = entity.getContent();
String videoInfo = getStringFromInputStream(encoding, instream);
if (videoInfo != null && videoInfo.length() > 0) {
List<NameValuePair> infoMap = new ArrayList<NameValuePair>();
URLEncodedUtils.parse(infoMap, new Scanner(videoInfo), encoding);
String downloadUrl = null;
String filename = videoId;
for (NameValuePair pair : infoMap) {
String key = pair.getName();
String val = pair.getValue();
log.finest(key + "=" + val);
if (key.equals("title")) {
filename = val;
} else if (key.equals("fmt_url_map")) {
String[] formats = commaPattern.split(val);
boolean found = false;
for (String fmt : formats) {
String[] fmtPieces = pipePattern.split(fmt);
if (fmtPieces.length == 2) {
int pieceFormat = Integer.parseInt(fmtPieces[0]);
log.fine("Available format=" + pieceFormat);
if (pieceFormat == format) {
// found what we want
downloadUrl = fmtPieces[1];
found = true;
break;
}
}
}
if (!found) {
log.warning("Could not find video matching specified format, however some formats of the video do exist (use -verbose).");
}
}
}
filename = cleanFilename(filename);
if (filename.length() == 0) {
filename = videoId;
} else {
filename += "_" + videoId;
}
filename += "." + extension;
File outputfile = new File(outputdir, filename);
if (downloadUrl != null) {
downloadWithHttpClient(userAgent, downloadUrl, outputfile);
} else {
log.severe("Could not find video");
}
} else {
log.severe("Did not receive content from youtube");
}
} else {
log.severe("Could not contact youtube: " + response.getStatusLine());
}
}
private static void downloadWithHttpClient(String userAgent, String downloadUrl, File outputfile) throws Throwable {
HttpGet httpget2 = new HttpGet(downloadUrl);
if (userAgent != null && userAgent.length() > 0) {
httpget2.setHeader("User-Agent", userAgent);
}
log.finer("Executing " + httpget2.getURI());
HttpClient httpclient2 = new DefaultHttpClient();
HttpResponse response2 = httpclient2.execute(httpget2);
HttpEntity entity2 = response2.getEntity();
if (entity2 != null && response2.getStatusLine().getStatusCode() == 200) {
double length = entity2.getContentLength();
if (length <= 0) {
// Unexpected, but do not divide by zero
length = 1;
}
InputStream instream2 = entity2.getContent();
System.out.println("Writing " + commaFormatNoPrecision.format(length) + " bytes to " + outputfile);
if (outputfile.exists()) {
outputfile.delete();
}
FileOutputStream outstream = new FileOutputStream(outputfile);
try {
byte[] buffer = new byte[BUFFER_SIZE];
double total = 0;
int count = -1;
int progress = 10;
long start = System.currentTimeMillis();
while ((count = instream2.read(buffer)) != -1) {
total += count;
int p = (int) ((total / length) * ONE_HUNDRED);
if (p >= progress) {
long now = System.currentTimeMillis();
double s = (now - start) / 1000;
int kbpers = (int) ((total / KB) / s);
System.out.println(progress + "% (" + kbpers + "KB/s)");
progress += 10;
}
outstream.write(buffer, 0, count);
}
outstream.flush();
} finally {
outstream.close();
}
System.out.println("Done");
}
}
private static String cleanFilename(String filename) {
for (char c : ILLEGAL_FILENAME_CHARACTERS) {
filename = filename.replace(c, '_');
}
return filename;
}
private static URI getUri(String path, List<NameValuePair> qparams) throws URISyntaxException {
URI uri = URIUtils.createURI(scheme, host, -1, "/" + path, URLEncodedUtils.format(qparams, DEFAULT_ENCODING), null);
return uri;
}
private void setupLogging(Level myLevel, Level globalLevel) {
changeFormatter(this);
explicitlySetAllLogging(myLevel, globalLevel);
}
#Override
public String format(LogRecord arg0) {
return arg0.getMessage() + newline;
}
private static void changeFormatter(Formatter formatter) {
Handler[] handlers = rootlog.getHandlers();
for (Handler handler : handlers) {
handler.setFormatter(formatter);
}
}
private static void explicitlySetAllLogging(Level myLevel, Level globalLevel) {
rootlog.setLevel(Level.ALL);
for (Handler handler : rootlog.getHandlers()) {
handler.setLevel(Level.ALL);
}
log.setLevel(myLevel);
rootlog.setLevel(globalLevel);
}
private static String getStringFromInputStream(String encoding, InputStream instream) throws UnsupportedEncodingException, IOException {
Writer writer = new StringWriter();
char[] buffer = new char[1024];
try {
Reader reader = new BufferedReader(new InputStreamReader(instream, encoding));
int n;
while ((n = reader.read(buffer)) != -1) {
writer.write(buffer, 0, n);
}
} finally {
instream.close();
}
String result = writer.toString();
return result;
}
}
/**
* <pre>
* Exploded results from get_video_info:
*
* fexp=909302
* allow_embed=1
* fmt_stream_map=35|http://v9.lscache8.c.youtube.com/videoplayback?ip=174.0.0.0&sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Calgorithm%2Cburst%2Cfactor&fexp=909302&algorithm=throttle-factor&itag=35&ipbits=8&burst=40&sver=3&expire=1294549200&key=yt1&signature=9E0A8E67154145BCADEBCF844CC155282548288F.2BBD0B2E125E3E533D07866C7AE91B38DD625D30&factor=1.25&id=4ba2193f7c9127d2||tc.v9.cache8.c.youtube.com,34|http://v6.lscache3.c.youtube.com/videoplayback?ip=174.0.0.0&sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Calgorithm%2Cburst%2Cfactor&fexp=909302&algorithm=throttle-factor&itag=34&ipbits=8&burst=40&sver=3&expire=1294549200&key=yt1&signature=6726793A7B041E6456B52C0972596D0D58974141.42B5A0573F62B85AEA7979E5EE1ADDD47EB9E909&factor=1.25&id=4ba2193f7c9127d2||tc.v6.cache3.c.youtube.com,18|http://v12.lscache7.c.youtube.com/videoplayback?ip=174.0.0.0&sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Calgorithm%2Cburst%2Cfactor&fexp=909302&algorithm=throttle-factor&itag=18&ipbits=8&burst=40&sver=3&expire=1294549200&key=yt1&signature=AE58398D4CC4D760C682D2A5B670B4047777FFF0.952E4FC4554E786FD937E7A89140E1F79B6DD8B7&factor=1.25&id=4ba2193f7c9127d2||tc.v12.cache7.c.youtube.com,5|http://v1.lscache7.c.youtube.com/videoplayback?ip=174.0.0.0&sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Calgorithm%2Cburst%2Cfactor&fexp=909302&algorithm=throttle-factor&itag=5&ipbits=8&burst=40&sver=3&expire=1294549200&key=yt1&signature=43434DCB6CFC463FF4522D9EE7CD019FE47237B1.C60A9522E361130938663AF2DAD83A5C2821AF5C&factor=1.25&id=4ba2193f7c9127d2||tc.v1.cache7.c.youtube.com
* fmt_url_map=35|http://v9.lscache8.c.youtube.com/videoplayback?ip=174.0.0.0&sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Calgorithm%2Cburst%2Cfactor&fexp=909302&algorithm=throttle-factor&itag=35&ipbits=8&burst=40&sver=3&expire=1294549200&key=yt1&signature=9E0A8E67154145BCADEBCF844CC155282548288F.2BBD0B2E125E3E533D07866C7AE91B38DD625D30&factor=1.25&id=4ba2193f7c9127d2,34|http://v6.lscache3.c.youtube.com/videoplayback?ip=174.0.0.0&sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Calgorithm%2Cburst%2Cfactor&fexp=909302&algorithm=throttle-factor&itag=34&ipbits=8&burst=40&sver=3&expire=1294549200&key=yt1&signature=6726793A7B041E6456B52C0972596D0D58974141.42B5A0573F62B85AEA7979E5EE1ADDD47EB9E909&factor=1.25&id=4ba2193f7c9127d2,18|http://v12.lscache7.c.youtube.com/videoplayback?ip=174.0.0.0&sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Calgorithm%2Cburst%2Cfactor&fexp=909302&algorithm=throttle-factor&itag=18&ipbits=8&burst=40&sver=3&expire=1294549200&key=yt1&signature=AE58398D4CC4D760C682D2A5B670B4047777FFF0.952E4FC4554E786FD937E7A89140E1F79B6DD8B7&factor=1.25&id=4ba2193f7c9127d2,5|http://v1.lscache7.c.youtube.com/videoplayback?ip=174.0.0.0&sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Calgorithm%2Cburst%2Cfactor&fexp=909302&algorithm=throttle-factor&itag=5&ipbits=8&burst=40&sver=3&expire=1294549200&key=yt1&signature=43434DCB6CFC463FF4522D9EE7CD019FE47237B1.C60A9522E361130938663AF2DAD83A5C2821AF5C&factor=1.25&id=4ba2193f7c9127d2
* allow_ratings=1
* keywords=Stefan Molyneux,Luke Bessey,anarchy,stateless society,giant stone cow,the story of our unenslavement,market anarchy,voluntaryism,anarcho capitalism
* track_embed=0
* fmt_list=35/854x480/9/0/115,34/640x360/9/0/115,18/640x360/9/0/115,5/320x240/7/0/0
* author=lukebessey
* muted=0
* length_seconds=390
* plid=AASZXXGQtTEDKwAw
* ftoken=null
* status=ok
* watermark=http://s.ytimg.com/yt/swf/logo-vfl_bP6ud.swf,http://s.ytimg.com/yt/swf/hdlogo-vfloR6wva.swf
* timestamp=1294526523
* has_cc=False
* fmt_map=35/854x480/9/0/115,34/640x360/9/0/115,18/640x360/9/0/115,5/320x240/7/0/0
* leanback_module=http://s.ytimg.com/yt/swfbin/leanback_module-vflJYyeZN.swf
* hl=en_US
* endscreen_module=http://s.ytimg.com/yt/swfbin/endscreen-vflk19iTq.swf
* vq=auto
* avg_rating=5.0
* video_id=S6IZP3yRJ9I
* token=vjVQa1PpcFNhI3jvw6hfEHivcKK-XY5gb-iszDMrooA=
* thumbnail_url=http://i4.ytimg.com/vi/S6IZP3yRJ9I/default.jpg
* title=The Story of Our Unenslavement - Animated
* </pre>
*/
You can't. Look here for further reading on what the API could handle:
YoutubeAPI
If you could get an InputStream on that, Google won't get any money for advertisement at all.
But you could parse the page of the video-url you got from the API and look for the real video-link inside the flash tags.
Now you can find it here now its available https://developers.google.com/youtube/android/player/sample-applications
Related
I'm receiving a motion JPEG stream via a servlet's post method. I cut out the JPEG images from the stream as they come and then write them to a Motion JPEG file (mjpeg), using the following structure:
--END
Content-Type: image/jpeg
Content-Length: <Length of following JPEG image in bytes>
<JPEG image data>
--END
After the last --END part, the next image starts.
The mjpeg file is created in the following way:
private static final String BOUNDARY = "END";
private static final Charset CHARSET = StandardCharsets.UTF_8;
final byte[] PRE_BOUNDARY = ("--" + BOUNDARY).getBytes(CHARSET);
final byte[] CONTENT_TYPE = "Content-Type: image/jpeg".getBytes(CHARSET);
final byte[] CONTENT_LENGTH = "Content-Length: ".getBytes(CHARSET);
final byte[] LINE_FEED = "\n".getBytes(CHARSET);
try (OutputStream out = new BufferedOutputStream(new FileOutputStream(targetFile))) {
for every image received {
onImage(image, out);
}
}
public void onImage(byte[] image, OutputStream out) {
try {
out.write(PRE_BOUNDARY);
out.write(LINE_FEED);
out.write(CONTENT_TYPE);
out.write(LINE_FEED);
out.write(CONTENT_LENGTH);
out.write(String.valueOf(image.length).getBytes(CHARSET));
out.write(LINE_FEED);
out.write(LINE_FEED);
out.write(image);
out.write(LINE_FEED);
out.write(LINE_FEED);
} catch (IOException e) {
e.printStackTrace();
}
}
Here is an example file.
Now, I'd like to read the mjpeg files again and do some processing on the contained images. For this, I build the following reader:
package de.supportgis.stream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
public class MediaConverter {
private static final String BOUNDARY = "END";
private static final Charset CHARSET = StandardCharsets.UTF_8;
private static final int READ_PRE_BOUNDARY = 1;
private static final int READ_CONTENT_TYPE = 2;
private static final int READ_CONTENT_LENGTH = 3;
private static final int READ_CONTENT = 4;
public static void createMovieFromMJPEG(String file) throws FileNotFoundException, IOException {
char LINE_FEED = '\n';
char[] PRE_BOUNDARY = new String("--" + BOUNDARY + LINE_FEED).toCharArray();
try (InputStream in = new FileInputStream(file);
Reader reader = new InputStreamReader(in, CHARSET);
Reader buffer = new BufferedReader(reader)) {
int r;
StringBuffer content_buf = new StringBuffer();
int mode = READ_PRE_BOUNDARY;
long content_length = 0;
int[] cmdBuf = new int[PRE_BOUNDARY.length];
int boundaryPointer = 0;
int counter = 0;
while ((r = reader.read()) != -1) {
System.out.print((char)r);
counter++;
if (mode == READ_PRE_BOUNDARY) {
if (r == PRE_BOUNDARY[boundaryPointer]) {
boundaryPointer++;
if (boundaryPointer >= PRE_BOUNDARY.length - 1) {
// Read a PRE_BOUNDARY
mode = READ_CONTENT_TYPE;
boundaryPointer = 0;
}
}
} else if (mode == READ_CONTENT_TYPE) {
if (r != LINE_FEED) {
content_buf.append((char)r);
} else {
if (content_buf.length() == 0) {
// leading line break, ignore...
} else {
mode = READ_CONTENT_LENGTH;
content_buf.setLength(0);
}
}
} else if (mode == READ_CONTENT_LENGTH) {
if (r != LINE_FEED) {
content_buf.append((char)r);
} else {
if (content_buf.length() == 0) {
// leading line break, ignore...
} else {
String number = content_buf.substring(content_buf.lastIndexOf(":") + 1).trim();
content_length = Long.valueOf(number);
content_buf.setLength(0);
mode = READ_CONTENT;
}
}
} else if (mode == READ_CONTENT) {
char[] fileBuf = new char[(int)content_length];
reader.read(fileBuf);
System.out.println(fileBuf);
mode = READ_PRE_BOUNDARY;
}
}
}
}
public static void main(String[] args) {
try {
createMovieFromMJPEG("video.mjpeg");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Note that this reader may not produce working JPEGs yet, as I'm still trying to debug the following error:
I read the value given at Content-length. I furthermore expect that when I read <content-length> of bytes after the Content-Length part into fileBuf (line 78), I end up with exactly the bytes of the image that I wrote in the prior step. However, fileBuf contains the whole image, as well as the metadata and half the bytes of the next image, which means it reads way too much.
I know that when it comes to saving, reading and encoding binary data, there are many things that can go wrong. Which mistake do I have the pleasure of making here?
Thanks in advance.
The mistake was, as several comments suggested, using a Reader instead of an InputStream. I assumed InputStreamReader to return provide the returned bytes of an Inputstream via a Reader interface, but instead it returned characters in a specificm encoding as seemingly all Readers do.
So, the saving logic for the mjpeg stream was ok and the corrected reader looks like this:
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
public class MediaConverter {
private static final String BOUNDARY = "END";
private static final Charset CHARSET = StandardCharsets.UTF_8;
private static final int READ_PRE_BOUNDARY = 1;
private static final int READ_CONTENT_TYPE = 2;
private static final int READ_CONTENT_LENGTH = 3;
private static final int READ_CONTENT = 4;
public static void createMovieFromMJPEG(String file) throws FileNotFoundException, IOException {
char LINE_FEED = '\n';
char[] PRE_BOUNDARY = new String("--" + BOUNDARY + LINE_FEED).toCharArray();
try (InputStream in = new FileInputStream(file);
BufferedInputStream reader = new BufferedInputStream(in);) {
int r;
StringBuffer content_buf = new StringBuffer();
int mode = READ_PRE_BOUNDARY;
long content_length = 0;
int[] cmdBuf = new int[PRE_BOUNDARY.length];
int boundaryPointer = 0;
int counter = 0;
while ((r = reader.read()) != -1) {
System.out.print((char)r);
counter++;
if (mode == READ_PRE_BOUNDARY) {
if (r == PRE_BOUNDARY[boundaryPointer]) {
boundaryPointer++;
if (boundaryPointer >= PRE_BOUNDARY.length - 1) {
// Read a PRE_BOUNDARY
mode = READ_CONTENT_TYPE;
boundaryPointer = 0;
}
}
} else if (mode == READ_CONTENT_TYPE) {
if (r != LINE_FEED) {
content_buf.append((char)r);
} else {
if (content_buf.length() == 0) {
// leading line break, ignore...
} else {
mode = READ_CONTENT_LENGTH;
content_buf.setLength(0);
}
}
} else if (mode == READ_CONTENT_LENGTH) {
if (r != LINE_FEED) {
content_buf.append((char)r);
} else {
if (content_buf.length() == 0) {
// leading line break, ignore...
} else {
String number = content_buf.substring(content_buf.lastIndexOf(":") + 1).trim();
content_length = Long.valueOf(number);
content_buf.setLength(0);
mode = READ_CONTENT;
}
}
} else if (mode == READ_CONTENT) {
byte[] fileBuf = new byte[(int)content_length];
reader.read(fileBuf);
System.out.println(fileBuf);
mode = READ_PRE_BOUNDARY;
}
}
}
}
public static void main(String[] args) {
try {
createMovieFromMJPEG("video.mjpeg");
} catch (IOException e) {
e.printStackTrace();
}
}
}
I made a simple java program that lets you create a stocks scanner/screener. There aren't many features yet, but there is a problem with existing features. I have a class that has a method that creates an array of all stock tickers and returns it. Here it is:
package classes;
import Utility.ArrayModification;
import variables.Ticker;
import java.io.*;
import java.util.Scanner;
public class Market {
public static Ticker[] getAllTickers() throws FileNotFoundException {
Ticker[] allTickers = {};
File currentDirectory = new File(new File("").getAbsolutePath());
String allTickersDirectory = currentDirectory + "\\src\\AllTickers.txt";
Scanner scanner = new Scanner(new File(allTickersDirectory));
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if(!(line.contains("^"))) {
allTickers = ArrayModification.appendTicker(allTickers, new Ticker(line));
}
}
return allTickers;
}
}
AllTickers.txt is a text file with the names of all tickers in it. I also have another class that stores a datatype, Ticker. Here it is:
package variables;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
public class Ticker {
private String savedSymbol;
public Ticker(String symbol) {
savedSymbol = symbol;
}
public String getTicker() {
return savedSymbol;
}
public Ticker setTicker(String symbol) {
savedSymbol = symbol;
return this;
}
public double getPrice() throws IOException {
try {
String stringURL = "https://markets.businessinsider.com/stocks/" + savedSymbol + "-stock";
URL url = new URL(stringURL);
URLConnection urlConn = url.openConnection();
InputStreamReader inStream = new InputStreamReader(urlConn.getInputStream());
BufferedReader buff = new BufferedReader(inStream);
String stringPrice = "-1";
String line = buff.readLine();
while (line != null) {
if (line.contains("price: ")) {
int target = line.indexOf("price: ");
int deci = line.indexOf(".", target);
int start = deci;
int stop = deci;
while (line.charAt(start) != ' ') {
start--;
}
while (line.charAt(stop) != ',') {
stop++;
}
stringPrice = line.substring(start + 1, stop);
break;
}
line = buff.readLine();
}
double price = Double.parseDouble(stringPrice);
return price;
}
catch(Exception e) {
return -1;
}
}
public double getMarketCap() throws IOException {
try {
String stringURL = "https://finviz.com/quote.ashx?t=" + savedSymbol;
URL url = new URL(stringURL);
URLConnection urlConn = url.openConnection();
InputStreamReader inStream = new InputStreamReader(urlConn.getInputStream());
BufferedReader buff = new BufferedReader(inStream);
String stringMarketCap = "-1";
double finalMarketCap = -1;
String line = buff.readLine();
while (line != null) {
if (line.contains(">Market Cap<")) {
int deci = line.indexOf(".");
int start = deci;
int stop = deci;
while (line.charAt(start) != '>') {
start--;
}
while (line.charAt(stop) != '<') {
stop++;
}
stringMarketCap = line.substring(start + 1, stop - 1);
double marketCap = Double.parseDouble(stringMarketCap);
if (line.charAt(stop - 1) == 'B') {
finalMarketCap = marketCap * 1000000000;
} else if (line.charAt(stop - 1) == 'M') {
finalMarketCap = marketCap * 1000000;
}
break;
}
line = buff.readLine();
}
return finalMarketCap;
}
catch(Exception e) {
return -1;
}
}
}
Using all of these, you can create a simple scanner that scans for stocks with a price of, for example, 0 - 15. You can do this by doing this:
import classes.Market;
import variables.Ticker;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
Ticker[] allTickers = Market.getAllTickers();
for(int i = 0; i< allTickers.length; i++){
Ticker ticker = allTickers[i];
if(ticker.getPrice() > 0 && ticker.getPrice() < 15) {
System.out.println(ticker.getTicker());
}
}
}
}
It prints out all of the qualifying stocks. However, it is EXTREMELY slow. So slow that it's basically unusable. It is this way because the ticker.getPrice() method has to connect to markets.businessinsider.com, extract the HTML code, find the correct index, and get the price for every single stock out of the 6000 in AllTIckers.txt. Would there be a way to do this faster?
I am looking for a freemarker feature like:
<#include "big_file.json" parse="true" encode="base64">
to include a file
parse the content of this file
encode the result as base64
I know this is not possible out of the box.
Is there a way to extend freemarker?
The solution is to use the: freemarker directives
To solve this example:
"grafana_dashboards": {
<#list_dir folder="./grafana_dashboards/" suffix="json"; dashboard_file, dashboard_name, dashboard_file_has_next>
${dashboard_name}": "<#encode enc="base64"><#include dashboard_file></#encode>"<#if (dashboard_file_has_next)>,</#if>
</#list_dir>
}
I add this both vars:
cfg = new Configuration(Configuration.VERSION_2_3_29);
...
final Map<String, Object> vars = new HashMap<>();
vars.put("list_dir", new xxx.freemarker.directives.ListDirDirective());
vars.put("encode", new xxx.freemarker.directives.EncodeDirective());
final Template temp = cfg.getTemplate(file.getName());
try ( //
final ByteArrayOutputStream bao = new ByteArrayOutputStream(); //
final Writer out = new OutputStreamWriter(bao); //
) {
temp.process(vars, out);
return bao.toString();
}
Here are the Directives:
EncodeDirective
package xxx.freemarker.directives;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.Base64;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.Function;
import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateScalarModel;
/**
* FreeMarker user-defined directive that progressively transforms the output of
* its nested content to given encoding.
*
*
* <p>
* <b>Directive info</b>
* </p>
*
* Parameters:
* <ul>
* <li><code>enc</code>: The name of the encoding to use. Possible options:
* "base64". Required.
* </ul>
* <p>
* Loop variables: None
* <p>
* Directive nested content: Yes
*/
public class EncodeDirective implements TemplateDirectiveModel {
private static final String PARAM_NAME_ENC = "enc";
private static final Map<String, Function<String, String>> encoder = new HashMap<>();
static {
encoder.put("base64", EncodeDirective::encodeBase64);
}
#SuppressWarnings({ "rawtypes", "unchecked" })
public void execute(final Environment env, final Map rawParams, final TemplateModel[] loopVars, final TemplateDirectiveBody body)
throws TemplateException, IOException {
final Params params = parseAndValidateParams(rawParams, loopVars);
// If there is non-empty nested content:
if (body != null) {
// Executes the nested body. Same as <#nested> in FTL, except
// that we use our own writer instead of the current output writer.
final EncodeFilterWriter writer = new EncodeFilterWriter(env.getOut(), params.getEncoderFunction());
body.render(writer);
writer.flush();
} else {
throw new RuntimeException("missing body");
}
}
/**
* A {#link Writer} that transforms the character stream to upper case and
* forwards it to another {#link Writer}.
*/
private static class EncodeFilterWriter extends Writer {
private StringBuffer buffer = new StringBuffer();
private final Writer out;
private final Function<String, String> encoder;
EncodeFilterWriter(final Writer out, final Function<String, String> encoder) {
this.out = out;
this.encoder = encoder;
}
public void write(final char[] cbuf, final int off, final int len) throws IOException {
buffer.append(cbuf, off, len);
}
public void flush() throws IOException {
out.write(encoder.apply(buffer.toString()));
out.flush();
}
public void close() throws IOException {
out.close();
}
}
private Params parseAndValidateParams(final Map<String, TemplateModel> params, final TemplateModel[] loopVars)
throws TemplateModelException {
boolean encParamSet = false;
final Params p = new Params();
final Iterator<Entry<String, TemplateModel>> paramIter = params.entrySet().iterator();
while (paramIter.hasNext()) {
final Entry<String, TemplateModel> ent = paramIter.next();
final String paramName = ent.getKey();
final TemplateModel paramValue = ent.getValue();
if (paramName.equals(PARAM_NAME_ENC)) {
if (!(paramValue instanceof TemplateScalarModel)) {
throw new TemplateModelException("The \"" + PARAM_NAME_ENC + "\" parameter must be a string.");
}
p.setEnc(((TemplateScalarModel) paramValue).getAsString());
encParamSet = true;
} else {
throw new TemplateModelException("Unsupported parameter: " + paramName);
}
}
if (!encParamSet) {
throw new TemplateModelException("The required \"" + PARAM_NAME_ENC + "\" paramter is missing.");
}
if (loopVars.length != 0) {
throw new TemplateModelException("This directive doesn't allow loop variables.");
}
return p;
}
#Data
private class Params {
private String enc;
public void setEnv(final String enc) {
this.enc = enc;
}
public String getEnv() {
return this.enc;
}
public Function<String, String> getEncoderFunction() throws TemplateModelException {
final Function<String, String> encoderFunc = encoder.get(enc.toLowerCase());
if (encoderFunc == null) {
throw new TemplateModelException("The required \"" + PARAM_NAME_ENC + "\" paramter, must be one of: " + encoder.keySet());
}
return encoderFunc;
}
}
private static String encodeBase64(final String in) {
try {
return Base64.getEncoder().encodeToString( //
in.getBytes("UTF-8"));
} catch (final UnsupportedEncodingException e) {
throw new IllegalArgumentException("The required \"" + PARAM_NAME_ENC + "\" paramter, encode error:: " + e.getMessage(), e);
}
}
}
ListDirDirective
package xxx.freemarker.directives;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import freemarker.cache.TemplateLoader;
import freemarker.core.Environment;
import freemarker.template.SimpleScalar;
import freemarker.template.TemplateBooleanModel;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateScalarModel;
/**
* FreeMarker user-defined directive for repeating a section of a template, that
* scan a folder on file system and loop through matching files.
*
*
* <p>
* <b>Directive info</b>
* </p>
*
* <p>
* Parameters:
* <ul>
* <li><code>folder</code>: The relative path of the folder on file system.
* Required.
* <li><code>suffix</code>: File ending too scan for. Required.
* </ul>
*
* Loop variables:
* <ul>
* <li><code>file_path</code>: String: The relative file path, used by
* "<#include" or "<#import". Required.</li>
* <li><code>file_name</code>: String: The file name without suffix.
* Optional.</li>
* <li><code>has_next</code>: Boolean: Indicator if it is last file or not.
* Optional.</li>
* </ul>
* <p>
* Nested content: Yes
*/
public class ListDirDirective implements TemplateDirectiveModel {
private static final String PARAM_NAME_FOLDER = "folder";
private static final String PARAM_NAME_SUFFIX = "suffix";
#SuppressWarnings({ "rawtypes", "unchecked" })
#Override
public void execute(final Environment env, final Map rawParams, final TemplateModel[] loopVars,
final TemplateDirectiveBody body) throws TemplateException, IOException {
final Path basePath = getCurrentTemplate(env).getParentFile().toPath();
final Params params = parseAndValidateParams(rawParams, loopVars);
final List<String> files = findFiles("**/*." + params.getSuffix(), basePath, params.getFolder());
if (files.isEmpty()) {
throw new IllegalArgumentException(
"No files found with suffix: " + params.getSuffix() + " using base path: " + params.getFolder());
}
if (body != null) {
final Iterator<String> filesIt = files.iterator();
while (filesIt.hasNext()) {
final String filePath = filesIt.next();
loopVars[0] = new SimpleScalar(filePath);
// Set file name without extension/suffix
if (loopVars.length > 1) {
loopVars[1] = new SimpleScalar(getFilennameWithoutSuffix(filePath, params.getSuffix()));
}
// Set has_next variable if set
if (loopVars.length > 2) {
loopVars[2] = filesIt.hasNext() ? TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
}
// Executes the nested body (same as <#nested> in FTL). In this
// case we don't provide a special writer as the parameter:
body.render(env.getOut());
}
}
}
private File getCurrentTemplate(final Environment env) throws IOException {
final TemplateLoader templateLoader = env.getConfiguration().getTemplateLoader();
final Object tmp = templateLoader.findTemplateSource(env.getCurrentTemplate().getSourceName());
if (!(tmp instanceof File)) {
throw new IllegalArgumentException("The ListDirDirective is only compatible with FileTemplateLoader");
}
return (File) tmp;
}
private static String getFilennameWithoutSuffix(final String filePath, final String suffix) {
final File file = new File(filePath);
return file.getName() //
.replace("\\.?" + Pattern.quote(suffix) + "$", "");
}
private static List<String> findFiles(final String pattern, final Path basePath, final String pathName)
throws IOException {
final Path path = basePath.resolve(pathName).toAbsolutePath();
final PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher("glob:" + pattern);
try (final Stream<Path> paths = Files.find(path, 10,
(currentPath, fileAttributes) -> pathMatcher.matches(currentPath))) {
return paths //
.map(basePath::relativize) //
.map(Path::toString) //
.collect(Collectors.toList());
}
}
private Params parseAndValidateParams(final Map<String, TemplateModel> params, final TemplateModel[] loopVars)
throws TemplateModelException {
boolean folderParamSet = false;
boolean suffixParamSet = false;
final Params p = new Params();
final Iterator<Entry<String, TemplateModel>> paramIter = params.entrySet().iterator();
while (paramIter.hasNext()) {
final Entry<String, TemplateModel> ent = paramIter.next();
final String paramName = ent.getKey();
final TemplateModel paramValue = ent.getValue();
if (paramName.equals(PARAM_NAME_FOLDER)) {
if (!(paramValue instanceof TemplateScalarModel)) {
throw new TemplateModelException(
"The \"" + PARAM_NAME_FOLDER + "\" parameter must be a string.");
}
p.setFolder(((TemplateScalarModel) paramValue).getAsString());
folderParamSet = true;
} else if (paramName.equals(PARAM_NAME_SUFFIX)) {
if (!(paramValue instanceof TemplateScalarModel)) {
throw new TemplateModelException(
"The \"" + PARAM_NAME_SUFFIX + "\" parameter must be a string.");
}
final String suffix = ((TemplateScalarModel) paramValue).getAsString();
if (!suffix.matches("[a-zA-Z0-9]{1,10}")) {
throw new TemplateModelException("The \"" + PARAM_NAME_SUFFIX + "\" parameter "
+ "must only contain letter and number and needs to be between 1-10 chars.");
}
p.setSuffix(suffix);
suffixParamSet = true;
} else {
throw new TemplateModelException("Unsupported parameter: " + paramName);
}
}
if (!folderParamSet) {
throw new TemplateModelException("The required \"" + PARAM_NAME_FOLDER + "\" paramter is missing.");
}
if (!suffixParamSet) {
throw new TemplateModelException("The required \"" + PARAM_NAME_SUFFIX + "\" paramter is missing.");
}
if (loopVars.length < 1) {
throw new TemplateModelException("At least 1 loop vars is required: file_name, [name], [has_next]");
}
if (loopVars.length > 3) {
throw new TemplateModelException("Max 3 loop vars are allowed: file_name, [name], [has_next]");
}
return p;
}
#Data
private class Params {
private String folder;
private String suffix;
public void setFolder(final String folder) {
this.folder = folder;
}
public String getFolder() {
return this.folder;
}
public void setSuffix(final String suffix) {
this.suffix = suffix;
}
public String getSuffix() {
return this.suffix;
}
}
}
How we can convert a dicom file(.dcm) to a jpeg image using java?
Here is my code:
import java.io.File;
import java.io.IOException;
import org.dcm4che2.tool.dcm2jpg.Dcm2Jpg;
public class MainClass {
public static void main(String[] args) throws IOException{
Dcm2Jpg conv = new Dcm2Jpg();
conv.convert(new File("C:\\Users\\lijo.joseph\\Desktop\\Dicom\\IM-0001-0001.dcm"), new File("C:\\Users\\lijo.joseph\\Desktop\\Dicom\\IM-0001-0001.jpg"));
}
}
and i am getting the following error while running the project
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/cli/ParseException
at MainClass.main(MainClass.java:7)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.cli.ParseException
at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 1 more
please help and thanks in advance
Here is the link Converting DICOM to JPEG using dcm4che 2
Following is my code which works perfectly.I have placed it with imports so it might be use-full.
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import org.dcm4che2.imageio.plugins.dcm.DicomImageReadParam;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
public class Examplke1 {
static BufferedImage myJpegImage=null;
public static void main(String[] args) {
File file = new File("test5/12840.dcm");
Iterator<ImageReader> iterator =ImageIO.getImageReadersByFormatName("DICOM");
while (iterator.hasNext()) {
ImageReader imageReader = (ImageReader) iterator.next();
DicomImageReadParam dicomImageReadParam = (DicomImageReadParam) imageReader.getDefaultReadParam();
try {
ImageInputStream iis = ImageIO.createImageInputStream(file);
imageReader.setInput(iis,false);
myJpegImage = imageReader.read(0, dicomImageReadParam);
iis.close();
if(myJpegImage == null){
System.out.println("Could not read image!!");
}
} catch (IOException e) {
e.printStackTrace();
}
File file2 = new File("/test.jpg");
try {
OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(file2));
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(outputStream);
encoder.encode(myJpegImage);
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Completed");
}
}
}
Jars Used to Run it
dcm4che-imageio-2.0.28.jar
dcm4che-image-2.0.28.jar
jai_imageio-1.1.jar
dcm4che-core-2.0.28.jar
slf4j-api-1.7.7.jar
slf4j-log4j12-1.7.7.jar
apache-logging-log4j.jar
Hope it helps.
This Code is used for Converting Dicom Image to JPG Image
import java.io.File;
import java.io.IOException;
public class Dcm2JpgTest {
public static void main(String[] args) throws IOException {
try{
File src = new File("d:\\Test.dcm");
File dest = new File("d:\\Test.jpg");
Dcm2Jpeg dcm2jpg= new Dcm2Jpeg();
dcm2jpg.convert(src, dest);
System.out.println("Completed");
} catch(IOException e){
e.printStackTrace();
} catch(Exception e){
e.printStackTrace();
}
}
}
Dcm2Jpeg.java File
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.List;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.dcm4che2.data.DicomObject;
import org.dcm4che2.imageio.plugins.dcm.DicomImageReadParam;
import org.dcm4che2.io.DicomInputStream;
import org.dcm4che2.util.CloseUtils;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
public class Dcm2Jpeg {
private static final String USAGE =
"dcm2jpg [Options] <dcmfile> <jpegfile>\n" +
"or dcm2jpg [Options] <dcmfile>... <outdir>\n" +
"or dcm2jpg [Options] <indir>... <outdir>";
private static final String DESCRIPTION =
"Convert DICOM image(s) to JPEG(s)\nOptions:";
private static final String EXAMPLE = null;
private int frame = 1;
private float center;
private float width;
private String vlutFct;
private boolean autoWindowing;
private DicomObject prState;
private short[] pval2gray;
private String fileExt = ".jpg";
private void setFrameNumber(int frame) {
this.frame = frame;
}
private void setWindowCenter(float center) {
this.center = center;
}
private void setWindowWidth(float width) {
this.width = width;
}
public final void setVoiLutFunction(String vlutFct) {
this.vlutFct = vlutFct;
}
private final void setAutoWindowing(boolean autoWindowing) {
this.autoWindowing = autoWindowing;
}
private final void setPresentationState(DicomObject prState) {
this.prState = prState;
}
private final void setPValue2Gray(short[] pval2gray) {
this.pval2gray = pval2gray;
}
public final void setFileExt(String fileExt) {
this.fileExt = fileExt;
}
public void convert(File src, File dest) throws IOException {
Iterator<ImageReader> iter = ImageIO.getImageReadersByFormatName("DICOM");
ImageReader reader = iter.next();
DicomImageReadParam param =
(DicomImageReadParam) reader.getDefaultReadParam();
param.setWindowCenter(center);
param.setWindowWidth(width);
param.setVoiLutFunction(vlutFct);
param.setPresentationState(prState);
param.setPValue2Gray(pval2gray);
param.setAutoWindowing(autoWindowing);
ImageInputStream iis = ImageIO.createImageInputStream(src);
BufferedImage bi;
OutputStream out = null;
try {
reader.setInput(iis, false);
bi = reader.read(frame - 1, param);
if (bi == null) {
System.out.println("\nError: " + src + " - couldn't read!");
return;
}
out = new BufferedOutputStream(new FileOutputStream(dest));
JPEGImageEncoder enc = JPEGCodec.createJPEGEncoder(out);
enc.encode(bi);
} finally {
CloseUtils.safeClose(iis);
CloseUtils.safeClose(out);
}
//System.out.print('.');
}
public int mconvert(List<String> args, int optind, File destDir)
throws IOException {
int count = 0;
for (int i = optind, n = args.size() - 1; i < n; ++i) {
File src = new File(args.get(i));
count += mconvert(src, new File(destDir, src2dest(src)));
}
return count;
}
private String src2dest(File src) {
String srcname = src.getName();
return src.isFile() ? srcname + this.fileExt : srcname;
}
public int mconvert(File src, File dest) throws IOException {
if (!src.exists()) {
System.err.println("WARNING: No such file or directory: " + src
+ " - skipped.");
return 0;
}
if (src.isFile()) {
try {
convert(src, dest);
} catch (Exception e) {
System.err.println("WARNING: Failed to convert " + src + ":");
e.printStackTrace(System.err);
System.out.print('F');
return 0;
}
System.out.print('.');
return 1;
}
File[] files = src.listFiles();
if (files.length > 0 && !dest.exists()) {
dest.mkdirs();
}
int count = 0;
for (int i = 0; i < files.length; ++i) {
count += mconvert(files[i], new File(dest, src2dest(files[i])));
}
return count;
}
#SuppressWarnings("unchecked")
public static void main(String args[]) throws Exception {
CommandLine cl = parse(args);
Dcm2Jpeg dcm2jpg = new Dcm2Jpeg();
if (cl.hasOption("f")) {
dcm2jpg.setFrameNumber(
parseInt(cl.getOptionValue("f"),
"illegal argument of option -f",
1, Integer.MAX_VALUE));
}
if (cl.hasOption("p")) {
dcm2jpg.setPresentationState(loadDicomObject(
new File(cl.getOptionValue("p"))));
}
if (cl.hasOption("pv2gray")) {
dcm2jpg.setPValue2Gray(loadPVal2Gray(
new File(cl.getOptionValue("pv2gray"))));
}
if (cl.hasOption("c")) {
dcm2jpg.setWindowCenter(
parseFloat(cl.getOptionValue("c"),
"illegal argument of option -c"));
}
if (cl.hasOption("w")) {
dcm2jpg.setWindowWidth(
parseFloat(cl.getOptionValue("w"),
"illegal argument of option -w"));
}
if (cl.hasOption("sigmoid")) {
dcm2jpg.setVoiLutFunction(DicomImageReadParam.SIGMOID);
}
dcm2jpg.setAutoWindowing(!cl.hasOption("noauto"));
if (cl.hasOption("jpgext")) {
dcm2jpg.setFileExt(cl.getOptionValue("jpgext"));
}
final List<String> argList = cl.getArgList();
int argc = argList.size();
File dest = new File(argList.get(argc-1));
long t1 = System.currentTimeMillis();
int count = 1;
if (dest.isDirectory()) {
count = dcm2jpg.mconvert(argList, 0, dest);
} else {
File src = new File(argList.get(0));
if (argc > 2 || src.isDirectory()) {
exit("dcm2jpg: when converting several files, "
+ "last argument must be a directory\n");
}
dcm2jpg.convert(src, dest);
}
long t2 = System.currentTimeMillis();
System.out.println("\nconverted " + count + " files in " + (t2 - t1)
/ 1000f + " s.");
}
private static DicomObject loadDicomObject(File file) {
DicomInputStream in = null;
try {
in = new DicomInputStream(file);
return in.readDicomObject();
} catch (IOException e) {
exit(e.getMessage());
throw new RuntimeException();
} finally {
CloseUtils.safeClose(in);
}
}
private static short[] loadPVal2Gray(File file) {
BufferedReader r = null;
try {
r = new BufferedReader(new InputStreamReader(new FileInputStream(
file)));
short[] pval2gray = new short[256];
int n = 0;
String line;
while ((line = r.readLine()) != null) {
try {
int val = Integer.parseInt(line.trim());
if (n == pval2gray.length) {
if (n == 0x10000) {
exit("Number of entries in " + file + " > 2^16");
}
short[] tmp = pval2gray;
pval2gray = new short[n << 1];
System.arraycopy(tmp, 0, pval2gray, 0, n);
}
pval2gray[n++] = (short) val;
} catch (NumberFormatException nfe) {
// ignore lines where Integer.parseInt fails
}
}
if (n != pval2gray.length) {
exit("Number of entries in " + file + ": " + n
+ " != 2^[8..16]");
}
return pval2gray;
} catch (IOException e) {
exit(e.getMessage());
throw new RuntimeException();
} finally {
CloseUtils.safeClose(r);
}
}
private static CommandLine parse(String[] args) {
Options opts = new Options();
OptionBuilder.withArgName("frame");
OptionBuilder.hasArg();
OptionBuilder.withDescription(
"frame to convert, 1 (= first frame) by default");
opts.addOption(OptionBuilder.create("f"));
OptionBuilder.withArgName("prfile");
OptionBuilder.hasArg();
OptionBuilder.withDescription(
"file path of presentation state to apply");
opts.addOption(OptionBuilder.create("p"));
OptionBuilder.withArgName("center");
OptionBuilder.hasArg();
OptionBuilder.withDescription("Window Center");
opts.addOption(OptionBuilder.create("c"));
OptionBuilder.withArgName("width");
OptionBuilder.hasArg();
OptionBuilder.withDescription("Window Width");
opts.addOption(OptionBuilder.create("w"));
opts.addOption("sigmoid", false,
"apply sigmoid VOI LUT function with given Window Center/Width");
opts.addOption("noauto", false,
"disable auto-windowing for images w/o VOI attributes");
OptionBuilder.withArgName("file");
OptionBuilder.hasArg();
OptionBuilder.withDescription(
"file path of P-Value to gray value map");
opts.addOption(OptionBuilder.create("pv2gray"));
OptionBuilder.withArgName(".xxx");
OptionBuilder.hasArg();
OptionBuilder.withDescription(
"jpeg file extension used with destination directory argument,"
+ " default: '.jpg'.");
opts.addOption(OptionBuilder.create("jpgext"));
opts.addOption("h", "help", false, "print this message");
opts.addOption("V", "version", false,
"print the version information and exit");
CommandLine cl = null;
try {
cl = new GnuParser().parse(opts, args);
} catch (ParseException e) {
exit("dcm2jpg: " + e.getMessage());
throw new RuntimeException("unreachable");
}
if (cl.hasOption('V')) {
Package p = Dcm2Jpeg.class.getPackage();
System.out.println("dcm2jpg v" + p.getImplementationVersion());
System.exit(0);
}
if (cl.hasOption('h') || cl.getArgList().size() < 2) {
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp(USAGE, DESCRIPTION, opts, EXAMPLE);
System.exit(0);
}
return cl;
}
private static int parseInt(String s, String errPrompt, int min, int max) {
try {
int i = Integer.parseInt(s);
if (i >= min && i <= max)
return i;
} catch (NumberFormatException e) {
// parameter is not a valid integer; fall through to exit
}
exit(errPrompt);
throw new RuntimeException();
}
private static float parseFloat(String s, String errPrompt) {
try {
return Float.parseFloat(s);
} catch (NumberFormatException e) {
exit(errPrompt);
throw new RuntimeException();
}
}
private static void exit(String msg) {
System.err.println(msg);
System.err.println("Try 'dcm2jpg -h' for more information.");
System.exit(1);
}
}
Jars Files Used to Run this code
dcm4che-core-2.0.23.jar
dcm4che-image-2.0.23.jar
dcm4che-imageio-2.0.23.jar
dcm4che-imageio-rle-2.0.23.jar
slf4j-log4j12-1.5.0.jar
slf4j-api-1.5.0.jar
log4j-1.2.13.jar
commons-cli-1.2.jar
If you don't want to use direct Dcm2Jpg.java file then you can include below jar file.
dcm4che-tool-dcm2jpg-2.0.23.jar
In this jar you can import org.dcm4che2.tool.dcm2jpg.Dcm2Jpg this java file
In my quest to create a simple Java program to extract tweets from Twitter's streaming API, I have modified this (http://cotdp.com/dl/TwitterConsumer.java) code snippet to work with the OAuth method. The result is the below code, which when executed, throws a Connection Refused Exception.
I am aware of Twitter4J however I want to create a program that relies least on other APIs.
I have done my research and it looks like the oauth.signpost library is suitable for Twitter's streaming API. I have also ensured my authentication details are correct. My Twitter Access level is 'Read-only'.
I couldn't find a simple Java example that shows how to use the streaming API without relying on e.g. Twitter4j.
import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import oauth.signpost.OAuthConsumer;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
/**
* A hacky little class illustrating how to receive and store Twitter streams
* for later analysis, requires Apache Commons HTTP Client 4+. Stores the data
* in 64MB long JSON files.
*
* Usage:
*
* TwitterConsumer t = new TwitterConsumer("username", "password",
* "http://stream.twitter.com/1/statuses/sample.json", "sample");
* t.start();
*/
public class TwitterConsumer extends Thread {
//
static String STORAGE_DIR = "/tmp";
static long BYTES_PER_FILE = 64 * 1024 * 1024;
//
public long Messages = 0;
public long Bytes = 0;
public long Timestamp = 0;
private String accessToken = "";
private String accessSecret = "";
private String consumerKey = "";
private String consumerSecret = "";
private String feedUrl;
private String filePrefix;
boolean isRunning = true;
File file = null;
FileWriter fw = null;
long bytesWritten = 0;
public static void main(String[] args) {
TwitterConsumer t = new TwitterConsumer(
"XXX",
"XXX",
"XXX",
"XXX",
"http://stream.twitter.com/1/statuses/sample.json", "sample");
t.start();
}
public TwitterConsumer(String accessToken, String accessSecret, String consumerKey, String consumerSecret, String url, String prefix) {
this.accessToken = accessToken;
this.accessSecret = accessSecret;
this.consumerKey = consumerKey;
this.consumerSecret = consumerSecret;
feedUrl = url;
filePrefix = prefix;
Timestamp = System.currentTimeMillis();
}
/**
* #throws IOException
*/
private void rotateFile() throws IOException {
// Handle the existing file
if (fw != null)
fw.close();
// Create the next file
file = new File(STORAGE_DIR, filePrefix + "-"
+ System.currentTimeMillis() + ".json");
bytesWritten = 0;
fw = new FileWriter(file);
System.out.println("Writing to " + file.getAbsolutePath());
}
/**
* #see java.lang.Thread#run()
*/
public void run() {
// Open the initial file
try { rotateFile(); } catch (IOException e) { e.printStackTrace(); return; }
// Run loop
while (isRunning) {
try {
OAuthConsumer consumer = new CommonsHttpOAuthConsumer(consumerKey, consumerSecret);
consumer.setTokenWithSecret(accessToken, accessSecret);
HttpGet request = new HttpGet(feedUrl);
consumer.sign(request);
DefaultHttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(request);
BufferedReader reader = new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
while (true) {
String line = reader.readLine();
if (line == null)
break;
if (line.length() > 0) {
if (bytesWritten + line.length() + 1 > BYTES_PER_FILE)
rotateFile();
fw.write(line + "\n");
bytesWritten += line.length() + 1;
Messages++;
Bytes += line.length() + 1;
}
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Sleeping before reconnect...");
try { Thread.sleep(15000); } catch (Exception e) { }
}
}
}
}
I tried to simulate the code and found that the error was very simple. You should use https instead of http in the url :)