Android MediaPlayer seekTo not seeking to the right position - android-mediaplayer

I have a very simple app that seeks a particular position of an mp3 upon startup and starts the MediaPlayer from that position. I see, however, that while playing back the seek position is always shifted by about 2-3 seconds forward or backward. I have tried mp3s with 16, 32 and variable bitrates. Only wav files seem to be working fine but they are impractical due to their size for my purpose. Interestingly, if I calculate the seek manually (16*24000 in case of a 16 bit mp3 for instance) and pass it as offset to mp.setDataSource, it's working fine. I can't use this because I also need TimedText in my app, which doesn't work with offset. Would really appreciate help.
Here is the complete code:
package com.example.mediaplayertest;
import java.io.FileDescriptor;
import java.io.IOException;
import android.app.Activity;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
public class MainActivity extends Activity implements MediaPlayer.OnSeekCompleteListener{
static MediaPlayer mp = new MediaPlayer();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
AssetFileDescriptor afd = getAssets().openFd("English text only.mp3");
long length = afd.getLength();
FileDescriptor fd = afd.getFileDescriptor();
mp.reset();
mp.setDataSource(fd, 0, length);
afd.close();
mp.setOnSeekCompleteListener(this);
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.prepare();
mp.seekTo(24000);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void onSeekComplete(MediaPlayer mp) {
int pos = mp.getCurrentPosition();
//debug shows the pos value correctly as 24000
mp.start();
}
}

Your manual calculation is for offset in bytes, which is 16x24=384 KB. If mp3 is of 16 kbps, then you are roughly seeking to 192 seconds! Whereas, you are giving 24 seconds when calling seekTo(). What is the position you want?

Related

JavaFX: Display PDF in WebView

I need to display a PDF inside the default WebView of JavaFX. I assumed, that i would easily be able to do that like this.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
public class ShowPdfTest extends Application {
public static void main(String[] args) {
launch();
}
#Override
public void start(Stage primaryStage) throws Exception {
WebView webView = new WebView();
WebEngine engine = webView.getEngine();
Scene scene = new Scene(webView);
primaryStage.setScene(scene);
primaryStage.show();
// engine.load("https://www.google.com");
engine.load("http://www.orimi.com/pdf-test.pdf");
}
}
I was wrong. Nothing happens. It seems like the WebEngine has no built-in PDF-Renderer. I tried JxBrowser which worked fine, but is a rather costly alternative.
So is there any way to display a PDF directly inside the default WebView component?
JxBrowser which worked fine, but is a rather costly alternative.
If you your application is an open-source project, you can obtain the JxBrowser Open-Source license here.

Program doesn't wait for modal dialog

With this program I am attempting to have the user select a text file that is a representation of a 4x4 sudoku problem. My agent will then take this file and attempt to solve the sudoku puzzle.
The problem I'm running into is that I can't seem to figure out how to get the proper file selected, and then passed into the method call for processing.
This is the file selector class I've created. So far it successfully brings up a button, and when clicked brings up the computer's file structure so the user can select a file.
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
/**
* Created by neil on 7/12/17.
*/
public class file_selector {
public JPanel panel1;
public File file;
JButton button1;
public file_selector() {
final JFileChooser fc = new JFileChooser();
button1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int returnVal = fc.showOpenDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) {
file = fc.getSelectedFile();
System.out.println("You chose to open " + file.getName());
}
}
});
}
public File getFile() {
return file;
}
}
This is my main method in which I attempt to use the file that the user selected. When I put the function calls in a while loop (like it is currently) it never proceeds because the file is never set. If I don't put the function calls in a while loop, I get a nullPointerException error when I try to process the file because the file has a null value.
public class sudoku {
//create 2d array that represents the 16x16 world
public cell[][] world_array = new cell[15][15];
static File myFile;
ArrayList<String> world_constraints;
public static void main(String[] args) throws IOException {
JFrame frame = new JFrame("file_selector");
file_selector fs = new file_selector();
frame.setContentPane(fs.panel1);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
myFile = fs.getFile();
while(myFile != null) {
sudoku my_puzzle = new sudoku();
my_puzzle.solve_puzzle();
}
}
I've done a ton of searching and can't seem to find what's wrong with my file_selector class such that it isn't setting the user selected value for the file.
You call getFile immediately after showing the frame and before the user has opportunity to click anything. Since the condition for while is false, the loop ends immediately and the method doesn't do anything afterwards, in particular it never calls getFile again.
Two options:
Make the button solve the puzzle, not just set file (easier, just change actionPerformed method).
Make file_selector emit an event when a file is selected and add a listener to it (this can be a challenge for you).

Javafx slider: text as tick label

I just started to learn Javafx, and I really like it so far. However in my current project I would need to use text as the tick labels for the javafx slider. I googled it a lot, but couldn't find any help. So for example I would like a slider with 4-5 positions, and them being "bad", "good", etc. instead of 1,2,3,...
I know I could build a custom UI manually with labels placed at the correct places, but I need to generate the sliders with custom text, and diofferent length every time, so it wouldn't work. In swing it is possible to change the labels with a hashtable for example, so my question is, is it possible to do it in Javafx?
Here is a sample using slider.setLabelFormatter.
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Slider;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.StringConverter;
public class SlidingScale extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
Slider slider = new Slider(0, 3, 0);
slider.setMin(0);
slider.setMax(3);
slider.setValue(1);
slider.setMinorTickCount(0);
slider.setMajorTickUnit(1);
slider.setSnapToTicks(true);
slider.setShowTickMarks(true);
slider.setShowTickLabels(true);
slider.setLabelFormatter(new StringConverter<Double>() {
#Override
public String toString(Double n) {
if (n < 0.5) return "Novice";
if (n < 1.5) return "Intermediate";
if (n < 2.5) return "Advanced";
return "Expert";
}
#Override
public Double fromString(String s) {
switch (s) {
case "Novice":
return 0d;
case "Intermediate":
return 1d;
case "Advanced":
return 2d;
case "Expert":
return 3d;
default:
return 3d;
}
}
});
slider.setMinWidth(380);
HBox layout = new HBox(slider);
layout.setPadding(new Insets(30));
primaryStage.setScene(new Scene(layout));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
The sample above only works in Java 8 due to a bug in JavaFX 2.2.
Some of the labels disappear as you make the the slider smaller, so I set a min width on the slider so that the labels remain (an alternate solution, might be to set a new label formatter with abbreviated labels used if the slider is sized small).
You might also be interested in voting for or commenting on the following feature request: RT-27863 A LabelFormatter isn't enough to customize Slider ticks.

Error Loading image from asset folder through Implicit Intent by using Phone's Image viewer

I am trying to display different London Tube maps through mobile's camera image viewer app by using implicit Intent. I had tube_map.gif image file in asset folder but when i try to load this file, app displays unable to find item. I think the file path i am specifying is not correct. I have followed the following video. the only difference is that in video, image file is stored on phone's SD Card while in my case, it is stored in asset folder. Video can be seen by this link. My code is as follows:
package uk.ac.kingston.mobileTechnology.k1059045.trainCountdown;
import java.io.File;
import uk.ac.kingston.mobileTechnology.k1059045.trainCountdown.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.webkit.WebView;
import android.widget.ImageView;
import android.widget.Toast;
public class ViewTubeMap extends Activity{
String[] maps = {"TUBE","NATIONAL RAIL","OVERGROUND","DLR","TRAMLINK","RIVER BUS","TOURISTS (Tube Map)","TOURISTS (Bus Map)","RAIL CONNECTIONS","TOILET FACILITIES"};
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
//setContentView(R.layout.tube_map_layout);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Pick a Map");
builder.setItems(maps, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// The 'which' argument contains the index position
// of the selected item
switch(which){
case(0):
makeToast("Case 0");
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
File image = new File("assets/tube_map.gif");
intent.setDataAndType(Uri.fromFile(image), "image/*");
startActivity(intent);
break;
case(1):
makeToast("Case 1");
break;
case(2):
makeToast("Case 2");
break;
case(3):
makeToast("Case 3");
break;
case(4):
makeToast("Case 4");
break;
case(5):
makeToast("Case 5");
break;
case(6):
makeToast("Case 6");
break;
case(7):
makeToast("Case 7");
break;
case(8):
makeToast("Case 8");
break;
case(9):
makeToast("Case 9");
break;
}
}
});
builder.create();
builder.show();
}
public void makeToast(String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
}
can anyone please guide me what's wrong with my code or how can i access my image and display it in phone's camera image view app? Thanks
assets is a private area of an app, so, fortunately no other app can access this area of another app. I would either make a workaround via SD card (option 1) or make the tubeMaps available via the internet (not locally) and obtain images from there (option 2).
Option 1:
you add a permission to access external storage. On the activity start you synchronize the images from local assets to external storage and then slightly change your code to pass another file object along with ACTION_VIEW intent pointing to external storage.
Option 2:
you upload the tubemaps somewhere on the internet and provide a url to the ACTION_VIEW intent.

How to implement Mouse Look in Java3d

I'm at a loss here. I've got a simple terrain generation algorithm working, and I've got some simple keyboard navigation working by extending ViewPlatformAWTBehavior and handling my own events. That's all well and good, and I can follow terrain. Hooray!
What I'd like to do is get some simple "mouse look" working. MouseRotate is close, but I'm looking for something more like an FPS ... where you aren't going to roll the camera, you're limited to 90 degrees vertical (up or down), and the mouse cursor is captured by the JFrame (with an escape).
I just can't seem to get it to work. I can capture the mouse event just fine, and mouseMoved works. I could probably just use an invisible cursor, and that would get me a large part of the way there (maybe), but I'd be stuck when trying to keep the mouse in the screen ... as soon as you're out of the frame, the mouse would be visible and stop rotating the view.
I keep thinking I must be going about this wrong, because this has to be a fairly common implementation, but I can't find anything on it.
Does anyone have some pointers or references?
If you want this is the code to make a full screen window which will help you with mouse problems
package fullscreen;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class FullScreen extends JFrame{
private JPanel contentPane = new JPanel();
private JButton fullscreenButton = new JButton("Fullscreen Mode");
private boolean Am_I_In_FullScreen = false;
private int PrevX,PrevY,PrevWidth,PrevHeight;
public static void main(String[] args) {
FullScreen frame = new FullScreen();
frame.setSize(600,500);
frame.setVisible(true);
}
public FullScreen(){
super("My FullscreenJFrame");
setContentPane(contentPane);
//From Here starts the trick
FullScreenEffect effect = new FullScreenEffect();
fullscreenButton.addActionListener(effect);
contentPane.add(fullscreenButton);
fullscreenButton.setVisible(true);
}
private class FullScreenEffect implements ActionListener{
#Override
public void actionPerformed(ActionEvent arg0) {
if(Am_I_In_FullScreen == false){
PrevX = getX();
PrevY = getY();
PrevWidth = getWidth();
PrevHeight = getHeight();
dispose(); //Destroys the whole JFrame but keeps organized every Component
//Needed if you want to use Undecorated JFrame
//dispose() is the reason that this trick doesn't work with videos
setUndecorated(true);
setBounds(-10,-100,getToolkit().getScreenSize().width+30,getToolkit()
.getScreenSize().height+110);
setVisible(true);
Am_I_In_FullScreen = true;
}
else{
setVisible(true);
setBounds(PrevX, PrevY, PrevWidth, PrevHeight);
dispose();
setUndecorated(false);
setVisible(true);
Am_I_In_FullScreen = false;
}
}
}
}