Parse and Play a .pls file in Android - android

can anybody help me how to parse and play this .pls file in android
[playlist]
NumberOfEntries=1
File1=http://stream.radiosai.net:8002/

A quick search resulted in this very basic PlsParser from the NPR app that, by the looks of it, will simply parse the .pls file and return all embedded URLs in a list of strings. You'll probably want to take a look at that as a starting point.
After that, you should be able to feed the URL to a MediaPlayer object, although I'm not completely sure about what formats/protocols are supported, or what limitations might apply in the case of streaming. The sequence of media player calls will look somewhat like this.
MediaPlayer mp = new MediaPlayer();
mp.setDataSource("http://stream.radiosai.net:8002/");
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.prepare(); //also consider mp.prepareAsync().
mp.start();
Update: As far as I can tell, you can almost literally take the referenced code and put it your own use. Note that the code below is by no means complete or tested.
public class PlsParser {
private final BufferedReader reader;
public PlsParser(String url) {
URLConnection urlConnection = new URL(url).openConnection();
this.reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
}
public List<String> getUrls() {
LinkedList<String> urls = new LinkedList<String>();
while (true) {
try {
String line = reader.readLine();
if (line == null) {
break;
}
String url = parseLine(line);
if (url != null && !url.equals("")) {
urls.add(url);
}
} catch (IOException e) {
e.printStackTrace();
}
}
return urls;
}
private String parseLine(String line) {
if (line == null) {
return null;
}
String trimmed = line.trim();
if (trimmed.indexOf("http") >= 0) {
return trimmed.substring(trimmed.indexOf("http"));
}
return "";
}
}
Once you have that, you can simply create a new PlsParser with the url of the .pls file and call getUrls afterwards. Each list item will be a url as found in the .pls file. In your case that'll just be http://stream.radiosai.net:8002/. As said, you can then feed this to the MediaPlayer.

Related

Load simple JSON file into 2 dimensional Array in Android

Driving myself crazy over the simplest thing. I have a JSON file called config.txt. The file is shown below.
{
"UsePipesInGuestData": true
}
All I want to do is get a 2 dimensional array such that:
Array[0] = UsePipesInGuestData and
Array[1] = true
I have been trying for 4 hours with various attempts, my most recent is shown below:
private void getConfig(){
//Function to read the config information from config.txt
FileInputStream is;
BufferedReader reader;
try {
final File configFile = new File(Environment.getExternalStorageDirectory().getPath() + "/guestlink/config.txt");
if (configFile.exists()) {
is = new FileInputStream(configFile);
reader = new BufferedReader(new InputStreamReader(is));
String line = reader.readLine();
while (line != null) {
line = reader.readLine();
if(line!= null) {
line = line.replace("\"", ""); //Strip out Quotes
line = line.replace(" ", ""); //Strip out Spaces
if ((!line.equals("{")) || (!line.equals("}"))) {
} else {
String[] configValue = line.split(":");
switch (configValue[0]) {
case "UsePipesInGuestData":
if (configValue[1].equals("true")) {
sharedPreferences.edit().putString("UsePipes", "true").apply();
} else {
sharedPreferences.edit().putString("UsePipes", "false").apply();
}
break;
}
}
}
}
reader.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
I cannot seem to ignore the lines with the { and } in them.
Clearly there MUST be an easier way. JAVA just seems to take an extremely large amount of code to do the simplest thing. Any help is greatly appreciated.
I believe your condition is incorrect. You try to read the file in the else of the condition (!line.equals("{")) || (!line.equals("}")). Simplifying, your code will run when the following happens:
!(!{ || !}) => { && } (applying De Morgan's law)
This means you will only run your code when the line is "{" AND it is "}" which is a contradiction. Try using simple conditions, like (!line.equals("{")) && (!line.equals("}")) (this is when you want to execute your code).
Additionally, you may be getting end of line characters (\n) in your string, which will make your condition fail ("{\n" != "{"). I suggest you debug and see the actual values you're getting in those lines.

Read all lines from BufferedReader before continuing

I am having a bit of an issue with my app. I receive a data through a socket, via a BufferedReader. I loop round with while ((sLine = reader.readLine ()) != null) and append the sLine to a StringBuilder object. I also spend a new line \n to the builder.
The plan is that once the builder is all finished, String sTotal = builder.toString()is called and a total is passed to the next routine.
However, the next routine is instead being called once for each line rather than with the string as a whole. The routine call is outside the loop above so I really don't know why!
Hope someone can help...
Edit: Code extract below.
public void run() {
try {
oServerSocket = new ServerSocket(iPort);
while ((!Thread.currentThread().isInterrupted()) && (!bStopThread)) {
try {
oSocket = oServerSocket.accept();
this.brInput = new BufferedReader(new InputStreamReader(this.oSocket.getInputStream()));
StringBuilder sbReadTotal = new StringBuilder();
String sReadXML = "";
while ((sReadXML = brInput.readLine()) != null) {
sbReadTotal.append("\n");
sbReadTotal.append(sReadXML);
}
sReadXML = sbReadTotal.toString();
Log.d("XMLDATA", sReadXML);
processXML(sReadXML);
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
/* Nothing Yet */
e.printStackTrace();
}
}
If you're exiting your internal while loop, it means you reached the end of your input stream (that's when readLine() returns null according to the docs).
You should be looking into the client, and not the server. What's establishing the client socket? Are you sure it's not establishing a separate connection for each line it sends?

Download thumbnail of file from Google Drive

I can download the original file from Google Drive by using the following code :
public static InputStream downloadFile(Drive service, File file)
throws IOException {
if (file.getDownloadUrl() != null && file.getDownloadUrl().length() > 0) {
try {
HttpResponse resp = service.getRequestFactory()
.buildGetRequest(new GenericUrl(file.getDownloadUrl()))
.execute();
return resp.getContent();
} catch (IOException e) {
// An error occurred.
e.printStackTrace();
return null;
}
} else {
// The file doesn't have any content stored on Drive.
return null;
}
}
But it looks like the connection really low when downloading many files to add into the grid view.
Therefore, I need to list thumb nail instead of original file as it will be better for the connection.
Please help me how?
Use File.getThumbnail method to get the thumbnail or File.getIconLink to get the icon link.

Need help debugging my code

I need some input about my code.
Basically, I have a method to load music from Class A
public void onListItemClick(ListView parent, View v, int position, long id){
musicIndex = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
cursor.moveToPosition(position);
filePath = cursor.getString(musicIndex);
fileName = new File(filePath).getName();
playMusic();//Play the selected music
}
public void playMusic(){
if(mPlayer.isPlaying()){
mPlayer.reset();
}
try{
mPlayer.setDataSource(filePath);
mPlayer.prepare();
mPlayer.start();
BeatDetection beatDetect = new BeatDetection();
beatDetect.init();
}catch (Exception e){
}
}
That method will call the init() method in Class B
public void init() throws Exception{
energy = 0;
variance = 0;
constant = 0;
isBeat = false;
sensitivity = 0;
dBuffer = new float[sampleRate / bufferSize];
eBuffer = new float[sampleRate / bufferSize];
timer = System.currentTimeMillis();
MusicLoad msc = new MusicLoad();
totalMs = 0;
seeking = true;
//msc.printText();
decode(msc.fileName, 25, 40);
}
In that method, it initializes everything and call the decode() method
public void decode(String path, int startMs, int maxMs)
throws IOException, javazoom.jl.decoder.DecoderException {
debug();
File in = new File(path);
InputStream inStream = new BufferedInputStream(new FileInputStream(in), 8 * 1024);
ByteArrayOutputStream outStream = new ByteArrayOutputStream(1024);
try {
Bitstream bitstream = new Bitstream(inStream);
Decoder decoder = new Decoder();
boolean done = false;
while (! done) {
Header frameHeader = bitstream.readFrame();
if (frameHeader == null) {
done = true;
} else {
totalMs += frameHeader.ms_per_frame();
if (totalMs >= startMs) {
seeking = false;
}
if (! seeking) {
SampleBuffer output = (SampleBuffer) decoder.decodeFrame(frameHeader, bitstream);
if (output.getSampleFrequency() != 44100 || output.getChannelCount() != 2) {
throw new javazoom.jl.decoder.DecoderException("mono or non-44100 MP3 not supported", null);
}
short[] pcm = output.getBuffer();
for (short s : pcm) {
outStream.write(s & 0xff);
outStream.write((s >> 8 ) & 0xff);
}
}
if (totalMs >= (startMs + maxMs)) {
done = true;
}
}
bitstream.closeFrame();
}
byte[] abAudioData = outStream.toByteArray();
calculation(abAudioData);
} catch (BitstreamException e) {
throw new IOException("Bitstream error: " + e);
} catch (DecoderException e) {
Log.w("Decoder error", e);
throw new javazoom.jl.decoder.DecoderException("Error",e);
} finally {
inStream.close();
}
}
Don't mind reading all the code lines. If you guys notice I put debug() in the beginning to see whether the method is called or not. At this point, the debug() is properly called. However, if I put the debug() after the line File in = new File(path);, the debug() will not be called anymore. It seems like the code is stop running at that point.
The ultimate result is, I can load and play the song without any problem. However, the decode() is not called and there is no error whatsoever. I'm stuck at pointing out the problem at this point. So if there's any input please help me.
EDIT: After I tried tracing the "path" variable, it returns NULL so the error is NullPointerException. Seems like the "fileName" variable from Class A is not passed to Class B. Any suggestion?
If you are using Eclipse with ADT then it's very easy to debug your Android apps, just add a breakpoint (probably in the new File(...) line) and see what happens.
My guess here is that File in = new File(path); probably is throwing a IOException in your decode method, that exception is bubbling first to init() and then to playMusic(), where it is caught by try catch block. Your catch is empty so you are not seeing anything. Try debugging as I said or add some logging info in the catch block.
This is just something to look at, but from the doc page
http://developer.android.com/reference/java/io/File.html#File%28java.lang.String%29
"The actual file referenced by a File may or may not exist. It may also, despite the name File, be a directory or other non-regular file."
If you had the path wrong, it may be trying to create the file and you may not have the correct permission to do so. Perhaps: WRITE_EXTERNAL_STORAGE.
I know this post is old, but I just wanted to show how to get the file path to read/write files for others that come across this post as I have:
String filePath = myContext.getFilesDir().getPath().toString() + "/sysout.log";
File file = new File(filePath);
These two lines will create (open if it exists, and overwrite) a file named "sysout.log" in the folder /data/data/com.app.name/files/; myContext is just the current context. Using this technique alleviates problems with defining your own path name. Hope this helps someone.

How to extract metadata from video(m3u8) files?

Is there any way to extract metadata from video(m3u8) files, If exist please help me with links or source code.
Thanks
m3u8 is the utf8 version of m3u instead c1252 charset.
m3u is a text file as a play list file with a content like:
#EXTM3U starts header and must be the first line
#EXTINF for each playable file.
In this link you can view samples:
http://schworak.com/programming/music/playlist_m3u.asp
And an overview for generalistic HTTP Streaming Architecture.
Code for the lazy dudes out there is below and detailed answered is here
private HashMap<String, Integer> parseHLSMetadata(InputStream i ){
try {
BufferedReader r = new BufferedReader(new InputStreamReader(i, "UTF-8"));
String line;
HashMap<String, Integer> segmentsMap = null;
String digitRegex = "\\d+";
Pattern p = Pattern.compile(digitRegex);
while((line = r.readLine())!=null){
if(line.equals("#EXTM3U")){ //start of m3u8
segmentsMap = new HashMap<String, Integer>();
}else if(line.contains("#EXTINF")){ //once found EXTINFO use runner to get the next line which contains the media file, parse duration of the segment
Matcher matcher = p.matcher(line);
matcher.find(); //find the first matching digit, which represents the duration of the segment, dont call .find() again that will throw digit which may be contained in the description.
segmentsMap.put(r.readLine(), Integer.parseInt(matcher.group(0)));
}
}
r.close();
return segmentsMap;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
Cheers.

Categories

Resources