I'm trying to show a video on the java ME 3.5 sdk emulator but I keep getting Unsupported Media Format 'video/mpeg-1', url='null' exception.
I also tried to change 'video/mpeg-1' to 'video/mpeg' but it still doesn't work. However it works fine when I lunch it on Wireless toolkit 2.5 emulator !
public void startApp() {
try {
if (error) {
return;
}
//display.setCurrent(list);
loadPlayer();
VideoControl videoControl = (VideoControl) player.getControl("javax.microedition.media.control.VideoControl");
if (videoControl == null) {
throw new Exception("No VideoControl!!");
}
videoControl.initDisplayMode(VideoControl.USE_DIRECT_VIDEO, canvas);
videoControl.setDisplayFullScreen(true);
videoControl.setVisible(true);
display.setCurrent(canvas);
player.start();
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void loadPlayer() throws Exception {
player = Manager.createPlayer(getClass().getResourceAsStream("/1.mpg"), "video/mpeg-1");
player.realize();
}
Related
I made a DRM media player app in Xamarin which drops course.licns and pass.licns files in internal memory in app directory for reading correct key.
It's working fine in Android 10 but it's not working in above versions like Android 11 and 12 when I put course name and key then app added both files but can't read it again when I want to play a video. The same thing is working fine on lower versions.
My code:
using System;
using System.Text;
using System.IO;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using Android.OS;
namespace MediaElement
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Add : ContentPage
{
public Add()
{
InitializeComponent();
}
async void Appears(object sender, EventArgs e)
{
try
{
this.FindByName<Entry>("ID").Text =Helper. GetIMEI();
}
catch (Exception e2)
{
await DisplayAlert("Error!", e2.Message, "Ok");
}
}
public static string Pass()
{
return Path.Combine((string)System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "pass.licns");
//return Path.Combine((string)System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData), "pass.licns");
}
public static string Course()
{
//return Path.Combine((string)System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData), "course.licns");
return Path.Combine((string)System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "course.licns");
}
void Register(object sender, EventArgs e)
{
try
{
string key = this.FindByName<Entry>("Key").Text.Trim();
string Name = this.FindByName<Entry>("Name").Text.Trim();
if (key== string.Empty || Name == string.Empty) { throw new Exception("Key or Name is empty"); }
if (!IsBase(key)) { throw new Exception("Invalid key!"); }
if (!IsValidID(key)) { throw new Exception("This key is not designed for your ID."); }
if (File.Exists(Pass()) && File.Exists(Course()))
{
if (File.ReadAllText(Pass()).Contains(key) || File.ReadAllText(Course()).Contains(Name)){ throw new Exception("Key or Course Already exists."); }
}
File.AppendAllText(Pass(), key+",");
File.AppendAllText(Course(), Name + ",");
DisplayAlert("Success", "License added successfully.", "Ok");
}
catch (Exception e2)
{
DisplayAlert("Error", e2.Message, "Ok");
}
}
bool IsBase(string base64)
{
try
{
if (base64 == Convert.ToBase64String(Convert.FromBase64String(base64))) { return true; }
}
catch (Exception)
{
}
return false;
}
public static bool IsValidID(string key)
{
return Encoding.ASCII.GetString(MainPage.Decrypt(Convert.FromBase64String(key),Helper. IDkey)).Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)[0].ToString() == Helper. GetIMEI();
}
}
}
Note:
I don't want to use All file access permissions due to so many restrictions in Google Play Store and my App is only accessing a particular file. Is there a proper way for upper versions?
I use the following code to record and play sounds with Java, but the volume is too low, how to make it louder, at least 2,3 times louder ?
public void Record_Audio(String File_Path,AudioFileFormat.Type File_Type)
{
try
{
audioFormat=getAudioFormat(); // Get things set up for capture
DataLine.Info dataLineInfo=new DataLine.Info(TargetDataLine.class,audioFormat);
targetDataLine=(TargetDataLine)AudioSystem.getLine(dataLineInfo);
//Create a thread to capture the microphone data into an audio file and start the thread running. It will run
// until the Stop button is clicked. This method will return after starting the thread.
new Record_Thread(File_Path,File_Type).start();
}
catch (Exception e)
{
System.out.println(e);
System.exit(0);
}
}
private void Play_Audio_Recording()
{
File Audio_File=new File(Current_Folder_Path+File_Name_ComboBox.getSelectedItem().toString().trim()+"."+Get_Audio_File_Type());
try
{
Audio_Clip=Applet.newAudioClip(Audio_File.toURI().toURL());
Audio_Clip.play();
}
catch (Exception e) { e.printStackTrace(); }
}
class Record_Thread extends Thread
{
String File_Path;
AudioFileFormat.Type File_Type;
Record_Thread(String File_Path) { this(File_Path,AudioFileFormat.Type.WAVE); }
Record_Thread(String File_Path,AudioFileFormat.Type File_Type)
{
this.File_Path=File_Path;
this.File_Type=File_Type;
}
public void run()
{
Audio_File=new File(File_Path);
try
{
targetDataLine.open(audioFormat);
targetDataLine.start();
AudioSystem.write(new AudioInputStream(targetDataLine),File_Type,Audio_File);
}
catch (Exception e) { e.printStackTrace(); }
}
}
You would use the FloatControl.Type (https://docs.oracle.com/javase/7/docs/api/javax/sound/sampled/FloatControl.Type.html) to set either the volume or the master gain. Something like:
targetDataLine=(TargetDataLine)AudioSystem.getLine(dataLineInfo);
javax.sound.sampled.FloatControl c = (FloatControl)targetDataLine.getControl(FloatControl.Type.VOLUME);
c.setValue(c.getMaximum());
might work.
I am trying to create an app in java using OpenCV to grab videostream from web service which is a camera system with couple of cameras and a recording device.
I have found the address "rtsp://login:pass#IP address:Port/cam/realmonitor?channel=1&subtype=0" for accessing the camera on channel 1.
For opening camera stream I have used this code (curently it catches a local usb camera):
VideoCapture cap;
Mat2Image mat2Img = new Mat2Image();
public VideoGrabber(){
cap = new VideoCapture(0);
try {
System.out.println("Sleeping..");
Thread.sleep(4000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Camera on..");
cap.open("0");
if(!cap.isOpened()){
System.out.println("Camera Error");
}
else{
System.out.println("Camera OK?");
}
}
After grabbing the video stream I put it into a JFrame.
I think I should put the video streaming service address in cap.open( ... ) but using rtsp://login:pass#http://192.168.1.14:8006/cam/realmonitor?channel=1&subtype=0 gave me "Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Width (0) and height (0) must be > 0".
Please help,
EDIT
I have found out that rtsp://login:pass#http://192.168.1.14:554/cam/realmonitor?channel=1&subtype=0 works in vlc but still no luck in opencv.
EDIT #2
Ok. After playing with vlcl, gstreamer and most of the popular solutions it just started working. I don't know if it wasn't bad rtsp address after all. Code:
static {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
//load the library of opencv
}
VideoCapture cap;
Mat2Image mat2Img = new Mat2Image();
Mat matFilter = new Mat();
public VideoGrabber(){
cap = new VideoCapture();
try {
System.out.println("Sleeping..");
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Camera on..");
cap.open("rtsp://login:pass#192.168.1.14:554/cam/realmonitor?channel=1&subtype=0");
if(!cap.isOpened()){
System.out.println("Camera Error");
}
else{
System.out.println("Camera OK?");
}
}
Answering my question and for Fouad I post the working code:
I am guessing the answer was loading ffmpeg dll.
//all the imports
public class App {
static {
String path = null;
try {
//I have copied dlls from opencv folder to my project folder
path = "E:\\JAVA Projects\\OpenCv\\RTSP Example\\libraries";
System.load(path+"\\opencv_java310.dll");
System.load(path+"\\opencv_ffmpeg310_64.dll");
} catch (UnsatisfiedLinkError e) {
System.out.println("Error loading libs");
}
}
public static void main(String[] args) {
App app = new App();
//Address can be different. Check your cameras manual. :554 a standard RTSP port for cameras but it can be different
String addressString = "rtsp://login:password#192.168.1.14:554/cam/realmonitor?channel=11&subtype=0";
Mat mat = new Mat();
VideoCapture capturedVideo = new VideoCapture();
boolean isOpened = capturedVideo.open(addressString);
app.openRTSP(isOpened, capturedVideo, mat);
}
public void openRTSP(boolean isOpened, VideoCapture capturedVideo, Mat cameraMat) {
if (isOpened) {
boolean tempBool = capturedVideo.read(cameraMat);
System.out.println("VideoCapture returned mat? "+tempBool);
if (!cameraMat.empty()) {
System.out.println("Print image size: "+cameraMat.size());
//processing image captured in cameraMat object
} else {
System.out.println("Mat is empty.");
}
} else {
System.out.println("Camera connection problem. Check addressString");
}
}
}
I am trying to implement simple logic to start/stop recording with MediaRecorder of Android.
The cycle is
connect to localSocket / set options / mRecorder.prepare();
mRecorder.start();
mRecorder.stop(); mRecorder.reset();
Then, loop between 2 and 3.
In the first cycle, 1,2,3 works fine as intended, however, I've got an error on the second start(restart) after the first stop.
com.example.app E/MediaRecorder﹕ start called in an invalid state: 1
What is the MediaRecorder state 1? What do I miss?
Thanks for your input.
if (cmd.equals("connect"))
{
try
{
sender.connect(new LocalSocketAddress(SOCKET_ADDRESS));
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.AAC_ADTS);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mRecorder.setOutputFile(sender.getFileDescriptor());
mRecorder.prepare();
}
catch (IOException e)
{ e.printStackTrace(); }
}
if (cmd.equals("start"))
{
try
{
mRecorder.start();
}
catch (IllegalStateException e)
{ e.printStackTrace(); }
}
if (cmd.equals("stop"))
{
try
{
mRecorder.stop();
mRecorder.reset();
}
catch (Exception e)
{ e.printStackTrace(); }
}
I'd had the same problem. I had to make a function initRecorder that sets up and prepares the media recorder. Then I called this function each time after the start button was pressed but before start was called. recreate() after stop also works.
StartRecording.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 100);
try {
try {
initRecorder(mHolder.getSurface());
} catch (IOException e) {
e.printStackTrace();
}
mMediaRecorder.start();
Log.e("mRecorder", "Started");
} catch (RuntimeException e) {
Log.e("mRecorder", "Start Failure");
e.printStackTrace();
}
}
});
private void initRecorder(Surface surface) throws IOException {
toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 1000);
if (mMediaRecorder == null) mMediaRecorder = new MediaRecorder();
// mMediaRecorder.setCamera(mCamera);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// mMediaRecorder.setOutputFormat(8);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
//mMediaRecorder.setVideoEncodingBitRate(512 * 1000);
mMediaRecorder.setVideoFrameRate(30);
// mMediaRecorder.setVideoSize(640,480);
mMediaRecorder.setPreviewDisplay(surface);
mMediaRecorder.setOutputFile(path);
// mMediaRecorder.setPreviewDisplay(mHolder.getSurface());
mMediaRecorder.setMaxDuration(10000); // 10 seconds
try {
mMediaRecorder.prepare();
Log.e("mRecorder", "Prepared");
} catch (IOException e) {
Log.e("mRecorder", "Prepare Failure");
e.printStackTrace();
}
mInitSuccesful = true;
}
In the scond cycle you have not called prepare, you need to call that before you can call start on media recorder
This is a self-answer, but I would not check as the answer because it's just work-around.
According to #Pulkit Sethi, state-1 means either MediaRecorder does not start properly or stop properly.
Perhaps, it's due to the local socket object sender.getFileDescriptor() as the target of setOutputFile.
So far, it's way too complicated and I could not find a way to stop gracefully enough to re-start or re-use MediaRecorder, I chose to dispose all everytime.
So
The cycle is
start localSocket/Server
connect to localSocket / set options / mRecorder.prepare();
mRecorder.start();
stop/close/release whole
This looks not the smartest way, but at least simple and stable, and I am happy with the result to start/stop/ & re-start as intended.
if (cmd.equals("stop"))
try
{
if (sender != null)
{
sender.close();
}
if (receiver != null)
{
receiver.close();
}
if (server != null)
{
server.close();
}
}
catch (IOException e)
{
e.printStackTrace();
}
sender = null;
receiver = null;
server = null;
}
for MediaRecorder
mRecorder.release();
The output file needs to be an actual file, not a socket. This is because MediaRecorder usually needs to be able to seek back in the file to update the header when the recording ends, and you can't seek in a socket.
public class Midlet extends MIDlet implements CommandListener{
Player p;
public void startApp() {
Display.getDisplay(this).setCurrent(new SongsList(this));
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
notifyDestroyed();
}
public void commandAction(Command cmnd, Displayable dsplbl) {
if (cmnd.getLabel().equals("Exit"))
{
destroyApp(true);
}
else
{
try {
//InputStream is = getClass().getResourceAsStream("/res/getlucky.mpeg");
//p = Manager.createPlayer(is, "audio/mpeg");
p = Manager.createPlayer("http://puu.sh/6n9jC.mp3");
p.realize();
p.start();
} catch (IOException ex) {
ex.printStackTrace();
} catch (MediaException ex) {
ex.printStackTrace();
}
}
}
}
this is the songslist class :
public class SongsList extends List{
public SongsList(Midlet midlet)
{
super("Songs", List.IMPLICIT);
append("get lucky", null);
addCommand(new Command("Exit", Command.EXIT, 0));
addCommand(new Command("Select", Command.OK, 0));
setCommandListener(midlet);
}
}
tried use via file stored in project (its under src/res):
inputStream = getClass().getResourceAsStream("res/getlucky.mpg");
audioPlayer = Manager.createPlayer(inputStream, "audio/mpg");
as well as from HTTP:
//audioPlayer = Manager.createPlayer("http://puu.sh/6n9jC.mp3");
Nothing works, what am I doing wrong?
EDIT:
I've tried to delete my application and just copy paste it to a new project and it worked for some reason.. now I encounter new problems:
1) I try to play a song - this is the link http://puu.sh/6n9jC.mp3
its not playing so I guess there's a limited file size for what can be played can someone tell me what is this limit ?
2) Im trying to record the audio with RecordPlayer but its always null
public AudioAnalyzer()
{
try {
thread = new Thread(this);
recordFinished = false;
//inputStream = getClass().getResourceAsStream("res/getlucky.mpg");
//audioPlayer = Manager.createPlayer(inputStream, "audio/mpg");
audioPlayer = Manager.createPlayer("http://puu.sh/35YTG.mp3");
//audioPlayer = Manager.createPlayer("http://puu.sh/6n9jC.mp3");
audioPlayer.realize();
System.out.println(System.getProperty("supports.audio.capture"));
recordControl = (RecordControl)audioPlayer.getControl("RecordControl");
recordOutput = new ByteArrayOutputStream();
recordControl.setRecordStream(recordOutput);
recordControl.startRecord();
audioPlayer.start();
//thread.start();
} catch (MediaException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
I even tried to print if the system is supporting audio capture and the result were true but I get NullPointException at this line :
recordOutput = new ByteArrayOutputStream();
although I tried to get the recordcontrol from the player it is still null :
recordControl = (RecordControl)audioPlayer.getControl("RecordControl");
I think I read that it'll always give NullPointerException unless you run it on a real device and not an emulator is that true ? can someone verify it ? and if so what can I do if I don't own a device currently any other way to use recordcontrol feature in emulator (assuming recordcontrol isn't working on emulators).
File size is 8MB (maybe play on your phone), try to this code
public void initMedia(final String aFileUrl) {
if (m_player == null) {
try {
m_player = Manager.createPlayer(aFileUrl);
m_player.addPlayerListener(this);
m_player.realize();
m_player.prefetch();
m_volumeControl = (VolumeControl) m_player.getControl("VolumeControl");
} catch (IOException ex) {
} catch (Exception ex) {
} catch (OutOfMemoryError e) {
}
}
}
In your code, i guess you miss "m_player.prefetch()", try this. And print your Exception message...
This code in general for file, resourcce, http...
public void initMedia(final String aProtocol, final String aMediaSource) {
if (m_player == null) {
try {
if (aMediaSource.indexOf("file://") == 0) {
InputStream iRecordStream = Connector.openInputStream(aMediaSource);
m_player = Manager.createPlayer(iRecordStream, "audio/amr");
} else {
m_player = Manager.createPlayer(aProtocol);
}
m_player.addPlayerListener(this);
m_player.realize();
boolean isPrefetch = true;
try {
m_player.prefetch();
} catch (Exception ex) {
isPrefetch = false;
}
// trick to pass prefetch error
if (!isPrefetch) {
if (m_player != null) {
m_player.close();
m_player = null;
}
if (aMediaSource.indexOf("file://") == 0) {
InputStream iRecordStream = Connector.openInputStream(aMediaSource);
m_player = Manager.createPlayer(iRecordStream, "audio/amr");
} else {
m_player = Manager.createPlayer(aProtocol);
}
m_player.addPlayerListener(this);
m_player.realize();
m_player.prefetch();
}
m_volumeControl = (VolumeControl) m_player.getControl("VolumeControl");
} catch (IOException ex) {
} catch (Exception ex) {
} catch (OutOfMemoryError e) {
}
}
}
In general when it comes to J2ME development, you should always test your app on multiple real devices.
Emulators can't be trusted.
Also, J2ME is very fragmented, and various devices have various bugs and behaves differently with the same code. This will affect any app on many areas. One area being audio playback.
For example, some devices requires that you use the realize() and prefetch() methods, while other devices will crash if you use prefetch(). The only possible solution (if you wish to support as many devices as possible) is to use multiple try/catch blocks.
See this link for a detailed explanation and other tips'n'tricks on audio playback with MIDP2.0
http://indiegamemusic.com/help.php?id=1