Xuggler screenRecording code affecting sound recording - java

I am working on an application for screencast with audio. screen recording with sound is working fine but the issue is that suppose I do recording of 5 mins then generated video file is of 5 min but generated audio file is of 4 min 45 sec. So basically the issue is that both audio and video are not in sync, audio file duration is less as compared to video file.
Both audio and video file recording are running in separate thread but still something is wrong.
VideoCapturing code:
public void run() {
setVideoParameters();
FRAME_RATE = frameRate;
// let's make a IMediaWriter to write the file.
writer = ToolFactory.makeWriter(movieFile.getName());
screenBounds = new Rectangle(RecorderSettings.m_CapRectX,
RecorderSettings.m_CapRecY,
(int) RecorderSettings.m_CapRectWidth,
(int) RecorderSettings.m_CapRecHeight);
// We tell it we're going to add one video stream, with id 0,
// at position 0, and that it will have a fixed frame rate of
// FRAME_RATE.
// ScreenWidth && ScreenHeight multiplied by 3/4 to reduce pixel to 3/4
// of actual.
// writer.addVideoStream(0, 0, ICodec.ID.CODEC_ID_MPEG4,
// screenBounds.width , screenBounds.height );
writer.addVideoStream(0, 0, vcodec.getID(),
(screenBounds.width * upperLimit) / lowerLimit,
(screenBounds.height * upperLimit) / lowerLimit);
// To have start time of recording
startTime = System.nanoTime();
while (isStopProceesBtnClk) {
try {
if (!isStopProceesBtnClk) {
break;
} else {
synchronized (this) {
while (isPauseProceesBtnClk) {
try {
// catches starting time of pause.
pauseStartTime = System.nanoTime();
wait();
} catch (Exception e) {
e.printStackTrace();
}
}
}
BufferedImage screen = getDesktopScreenshot();
// convert to the right image type
BufferedImage bgrScreen = convertToType(screen, BufferedImage.TYPE_3BYTE_BGR);
// encode the image to stream #0
if (totalPauseTime > 0) {
writer.encodeVideo(0, bgrScreen, (System.nanoTime() - startTime)- totalPauseTime, TimeUnit.NANOSECONDS);
} else {
writer.encodeVideo(0, bgrScreen, System.nanoTime() - startTime, TimeUnit.NANOSECONDS);
}
// sleep for frame rate milliseconds
try {
Thread.sleep((long) (1000 / FRAME_RATE));
} catch (InterruptedException e) {
// ignore
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
try {
writer.close();
writer = null;
Runtime.getRuntime().gc();
} catch (Exception e) {
// ignore errors
}
// tell the writer to close and write the trailer if needed
}
public static BufferedImage convertToType(BufferedImage sourceImage, int targetType) {
BufferedImage image;
// if the source image is already the target type, return the source
// image
if (sourceImage.getType() == targetType) {
image = sourceImage;
}
// otherwise create a new image of the target type and draw the new
// image
else {
image = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), targetType);
if (true) {
int x = MouseInfo.getPointerInfo().getLocation().x - 25;
int y = MouseInfo.getPointerInfo().getLocation().y - 37;
Graphics2D graphics2D = sourceImage.createGraphics();// getGraphics().drawImage(m_MouseIcon,
// x, y, 48, 48, null);
graphics2D.drawImage(SimpleWebBrowserExample.m_MouseIcon, x, y,
48, 48, null);
}
image.getGraphics().drawImage(sourceImage, 0, 0, null);
}
return image;
}
private BufferedImage getDesktopScreenshot() {
try {
// Robot captures screen shot
Robot robot = new Robot();
Rectangle captureSize = new Rectangle(screenBounds);
return robot.createScreenCapture(captureSize);
} catch (AWTException e) {
e.printStackTrace();
return null;
}
}
AudioCapturing Code:
public void run() {
init();
DataLine.Info info = new DataLine.Info(TargetDataLine.class,audioFormat,(int) (m_AudioFreq * sampleSizeInBytes));
try
{
m_TargetLine = (TargetDataLine) AudioSystem.getLine(info);
m_TargetLine.open(audioFormat, info.getMaxBufferSize());
}
catch(Exception exp){
exp.printStackTrace();
}
AudioFileFormat.Type targetType = AudioFileFormat.Type.WAVE;
try
{
m_outputFile = new File(bufferFileName);
while (m_outputFile.exists() && !m_outputFile.delete())
{
m_outputFile = BerylsUtility.getNextFile(m_outputFile);
}
FileOutputStream outFileStream = new FileOutputStream(m_outputFile);
audioOutStream = new BufferedOutputStream(outFileStream,memoryBufferSize);
}
catch (FileNotFoundException fe){
System.out.println("FileNotFoundException in VoiceCapturing.java :: " + fe);
}
catch (OutOfMemoryError oe){
System.out.println("OutOfMemoryError in VoiceCapturing.java " + oe);
}
while (isStopProceesBtnClk) {
try {
if (!isStopProceesBtnClk) {
break;
} else {
synchronized (this) {
while (isPauseProceesBtnClk) {
try {
wait();
} catch (Exception e) {
e.printStackTrace();
}
}
}
try
{
m_TargetLine.start();
int cnt = m_TargetLine.read(tempBuffer,0,tempBuffer.length);
if(cnt > 0){
audioOutStream.write(tempBuffer,0,cnt);
}
}
catch (Exception e){
System.out.println("Exception in VoiceCapturing.java :: " + e);
}
/*finally{
finish();
}*/
}
} catch (Exception e) {
e.printStackTrace();
}
}
finish();
}
public synchronized void finish()
{
try
{
System.out.println("AudioFinish");
audioOutStream.close();
FileInputStream audioInAgain = new FileInputStream(m_outputFile);
long sampleBytes = m_outputFile.length();
long sizeOfFrame = (long) m_SampleRate * m_Channels / 8;
BufferedInputStream buffAudioIn = new BufferedInputStream(audioInAgain, memoryBufferSize);
AudioInputStream a_input = new AudioInputStream(buffAudioIn, audioFormat, sampleBytes / sizeOfFrame);
while (m_AudioFile.exists() && !m_AudioFile.canWrite())
{
m_AudioFile = BerylsUtility.getNextFile(m_AudioFile);
}
AudioSystem.write(a_input, m_targetType, m_AudioFile);
buffAudioIn.close();
m_outputFile.delete();
}
catch (Exception e)
{
e.printStackTrace();
}
}
could someone guide me on this...
Thanks.

Related

Java Voice Chat Error

I am making a voice chat program. I have two servers one for voice and one for messages. When I connect two people I get this error, Thank you in advance. I attached the client code, ClientAudio code and the Client receive code
java.io.StreamCorruptedException: invalid type code: 00
at java.io.ObjectInputStream$BlockDataInputStream.readBlockHeader(ObjectInputStream.java:2508)
at java.io.ObjectInputStream$BlockDataInputStream.refill(ObjectInputStream.java:2543)
at java.io.ObjectInputStream$BlockDataInputStream.read(ObjectInputStream.java:2702)
at java.io.ObjectInputStream.read(ObjectInputStream.java:865)
at client.chat$ClientAudioRec.run(chat.java:388)
at java.lang.Thread.run(Thread.java:745)
its calling the error on
try {
bytesRead = ((ObjectInput) i2).read(inSound, 0, inSound.length);
} catch (Exception e) {
e.printStackTrace();
}
Code
public class Client implements Runnable { // CLIENT
private String msg;
public void run() {
try {
s1 = new Socket(ipAddress, port);
s2 = new Socket(ipAddress, 1210);
o1 = new ObjectOutputStream(s1.getOutputStream());
o1.writeObject(name);
serverListModel.addElement(name);
i1 = new ObjectInputStream(s1.getInputStream());
Thread voice = new Thread(new ClientAudio());
voice.start();
while(true) {
msg = (String) i1.readObject();
String[] namePart = msg.split("-");
if(namePart[0].equals("AddName") && !namePart[1].equals(name) && !serverListModel.contains(namePart[1])) {
serverListModel.addElement(namePart[1]);
}
if(namePart[0].equals("RemoveName") && !namePart[1].equals(name)) {
serverListModel.removeElement(namePart[1]);
}
if(!msg.equals(null) && !namePart[0].equals("AddName") && !namePart[0].equals("RemoveName")) {
chatWindow.append(msg+"\n");
}
}
} catch (IOException | ClassNotFoundException e) {
chatWindow.append("Server Closed");
e.printStackTrace();
try {
s1.close();
} catch (IOException e1) {
e1.printStackTrace();
}
mainWindow(true);
}
}
}
public class ClientAudio implements Runnable { // CLIENT AUDIO
public void run() {
try {
o2 = new ObjectOutputStream(s2.getOutputStream());
System.out.println("AUDIO");
int bytesRead = 0;
byte[] soundData = new byte[1];
Thread car = new Thread(new ClientAudioRec());
car.start();
while(true) {
bytesRead = mic.read(soundData, 0, bytesRead);
if(bytesRead >= 0) {
o2.write(soundData, 0, bytesRead);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class ClientAudioRec implements Runnable { // CLIENT AUDIO REC
public void run() {
i2 = new ObjectInputStream(s2.getInputStream());
System.out.println("REC");
SourceDataLine inSpeaker = null;
DataLine.Info info = new DataLine.Info(SourceDataLine.class, af);
try {
inSpeaker = (SourceDataLine)AudioSystem.getLine(info);
inSpeaker.open(af);
} catch (LineUnavailableException e1) {
System.out.println("ERROR 22");
e1.printStackTrace();
}
int bytesRead = 0;
byte[] inSound = new byte[100];
inSpeaker.start();
while(bytesRead != -1)
{
try{
bytesRead = ((ObjectInput) i2).read(inSound, 0, inSound.length);
} catch (Exception e){
e.printStackTrace();
}
if(bytesRead >= 0)
{
inSpeaker.write(inSound, 0, bytesRead);
}
}
}
}

Sending an image through socket as byte array in Java

I know this has been asked in a few different ways, but I've been working on this for 2 days with no avail. My code is failing in that the receiving side throws EOF exceptions constantly. Can someone point me in the right direction?
Receiving side:
class ReceiveThread extends Thread {
ReceiveThread() {
}
#Override
public void run() {
System.out.println("Receive Thread Start");
DataInputStream in;
try {
} catch (Exception e) {
return;
}
try {
in = new DataInputStream(connection.getInputStream());
while (true) {
if (!connection.isConnected()) {
System.out.println("Connection not connected");
break;
}
try {
int len = in.readInt();
byte[] data = new byte[len];
System.out.println("Image size: " + len);
if (len > 0) {
in.readFully(data, 0, len);
BufferedImage bi = ImageIO.read(new ByteArrayInputStream(data));
panel.updateImage(bi);
panel.repaint();
}
in.close();
} catch (Exception e) {
}
pause(100);
}
} catch (Exception e) {
}
}
public void pause(long time) {
try {
Thread.sleep(time);
} catch (Exception e) {
}
}
}
Sending side:
class UpdateScreenThread extends Thread {
Robot robot;
public UpdateScreenThread() {
try {
robot = new Robot();
System.out.println("Update Thread Created");
} catch (Exception e) {
}
}
#Override
public void run() {
System.out.println("Update Thread Running");
Settings.isSharing = true;
Dimension screenSize;
screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Rectangle screenRectangle = new Rectangle(screenSize);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream out;
try {
out = new DataOutputStream(s.getOutputStream());
} catch (Exception e) {
return;
}
while (s.isConnected()) {
//System.out.println("test");
BufferedImage bi = robot.createScreenCapture(screenRectangle);
try {
ImageIO.write(bi, "PNG", baos);
baos.flush();
byte[] bytes = baos.toByteArray();
out.flush();
out.writeInt(bytes.length);
out.flush();
out.write(bytes);
System.out.println("Image sent");
} catch (Exception e) {
}
pause(500);
}
try {
out.close();
} catch (Exception e) {
}
Settings.isSharing = false;
}
}
Thanks to anyone who can help. This is driving me INSANE.
Reduced to the essentials, this is your read loop:
public void run() {
//...
try {
in = new DataInputStream(connection.getInputStream());
while (true) {
//...
try {
int len = in.readInt();
byte[] data = new byte[len];
in.readFully(data, 0, len);
//...
in.close();
} catch (Exception e) {
}
pause(100);
}
} catch (Exception e) {
}
}
Note that the while (true) {...} includes in.close(). Move the close out of the loop.

Why Applet shuts the server down?

I am implementing a recording system using Java applet for my project but i am facing one problem during closing the applet, the applet shuts the server down.Is there any way to resolve this issue? I want to continue work on my project after completing the recording part but after recording when I close the applet it stops the server also So i need to restart the server again.
Any help or suggestion?
Code :-
public class Main extends JPanel implements ActionListener {
public Main() {
setLayout(new BorderLayout());
EmptyBorder eb = new EmptyBorder(5, 5, 5, 5);
SoftBevelBorder sbb = new SoftBevelBorder(SoftBevelBorder.LOWERED);
setBorder(new EmptyBorder(5, 5, 5, 5));
JPanel p1 = new JPanel();
// p1.setLayout(new BoxLayout(p1, BoxLayout.X_AXIS));
JPanel p2 = new JPanel();
p2.setBorder(sbb);
p2.setLayout(new BoxLayout(p2, BoxLayout.X_AXIS));
JPanel buttonsPanel = new JPanel();
buttonsPanel.setBorder(new EmptyBorder(10, 0, 5, 0));
radioGroup1 = new CheckboxGroup();
radio1 = new Checkbox("Record : ", radioGroup1,true);
p2.add(radio1);
playB = addButton("Play", buttonsPanel, false);
captB = addButton("Record", buttonsPanel, true);
closeA = addButton("Close", buttonsPanel, true);
p2.add(buttonsPanel);
p1.add(p2);
add(p1);
}
public void open() {
}
public void close() {
if (playback.thread != null) {
playB.doClick(0);
}
if (capture.thread != null) {
captB.doClick(0);
}
}
private JButton addButton(String name, JPanel p, boolean state) {
JButton b = new JButton(name);
b.addActionListener(this);
b.setEnabled(state);
p.add(b);
return b;
}
public void actionPerformed(ActionEvent e) {
Object obj = e.getSource();
if (obj.equals(playB)) {
if (playB.getText().startsWith("Play")) {
playback.start();
captB.setEnabled(false);
playB.setText("Stop");
} else {
playback.stop();
captB.setEnabled(true);
playB.setText("Play");
}
} else if (obj.equals(captB)) {
if (captB.getText().startsWith("Record")) {
capture.start();
playB.setEnabled(false);
captB.setText("Stop");
} else {
capture.stop();
playB.setEnabled(true);
}
}
else if(obj.equals(closeA)) {
System.exit(0);
}
}
public class Playback implements Runnable {
SourceDataLine line;
Thread thread;
public void start() {
errStr = null;
thread = new Thread(this);
thread.setName("Playback");
thread.start();
}
public void stop() {
thread = null;
}
private void shutDown(String message) {
if ((errStr = message) != null) {
System.err.println(errStr);
}
if (thread != null) {
thread = null;
captB.setEnabled(true);
playB.setText("Play");
}
}
public void run() {
AudioFormat format = getAudioFormat();
try {
audioInputStream = AudioSystem.getAudioInputStream(wavFile);
} catch (UnsupportedAudioFileException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
AudioInputStream playbackInputStream = AudioSystem.getAudioInputStream(format,
audioInputStream);
if (playbackInputStream == null) {
shutDown("Unable to convert stream of format " + audioInputStream + " to format " + format);
return;
}
// get and open the source data line for playback.
try {
line = (SourceDataLine) AudioSystem.getLine(info);
line.open(format, bufSize);
} catch (LineUnavailableException ex) {
shutDown("Unable to open the line: " + ex);
return;
}
// play back the captured audio data
int frameSizeInBytes = format.getFrameSize();
int bufferLengthInFrames = line.getBufferSize() / 8;
int bufferLengthInBytes = bufferLengthInFrames * frameSizeInBytes;
byte[] data = new byte[bufferLengthInBytes];
int numBytesRead = 0;
// start the source data line
line.start();
while (thread != null) {
try {
if ((numBytesRead = playbackInputStream.read(data)) == -1) {
break;
}
int numBytesRemaining = numBytesRead;
while (numBytesRemaining > 0) {
numBytesRemaining -= line.write(data, 0, numBytesRemaining);
}
} catch (Exception e) {
shutDown("Error during playback: " + e);
break;
}
}
// we reached the end of the stream.
// let the data play out, then
// stop and close the line.
if (thread != null) {
line.drain();
}
line.stop();
line.close();
line = null;
shutDown(null);
}
} // End class Playback
/**
* Reads data from the input channel and writes to the output stream
*/
class Capture implements Runnable {
TargetDataLine line;
Thread thread;
public void start() {
errStr = null;
thread = new Thread(this);
thread.setName("Capture");
thread.start();
}
public void stop() {
thread = null;
line.close();
//thread.stop();
}
private void shutDown(String message) {
if ((errStr = message) != null && thread != null) {
thread = null;
playB.setEnabled(true);
captB.setText("Record");
System.err.println(errStr);
}
}
public void run() {
duration = 0;
audioInputStream = null;
Playback pb = new Playback();
AudioFormat format = pb.getAudioFormat();
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
// get and open the target data line for capture.
try {
line = (TargetDataLine) AudioSystem.getLine(info);
// line.open(format, line.getBufferSize());
line.open(format);
line.start();
// saving audio file
AudioInputStream ais = new AudioInputStream(line);
// start recording
AudioSystem.write(ais, fileType, wavFile);
} catch (LineUnavailableException ex) {
shutDown("Unable to open the line: " + ex);
return;
} catch (SecurityException ex) {
shutDown(ex.toString());
//JavaSound.showInfoDialog();
return;
} catch (Exception ex) {
shutDown(ex.toString());
return;
}
// we reached the end of the stream.
// stop and close the line.
line.stop();
line.close();
line = null;
// stop and close the output stream
try {
out.flush();
out.close();
} catch (IOException ex) {
ex.printStackTrace();
}
// load bytes into the audio input stream for playback
byte audioBytes[] = out.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(audioBytes);
audioInputStream = new AudioInputStream(bais, format, audioBytes.length / frameSizeInBytes);
long milliseconds = (long) ((audioInputStream.getFrameLength() * 1000) / format
.getFrameRate());
duration = milliseconds / 1000.0;
try {
audioInputStream.reset();
} catch (Exception ex) {
ex.printStackTrace();
return;
}
}
} // End class Capture
}
This code don't look so good
else if(obj.equals(closeA)) {
System.exit(0);
}
this will cause the JVM to shutdown. I would have thought that you just want the applet to be in a stopped state.

lwuit video component floats over commands

My LWUIT video component floats over my commands. Any idea how I can fix this? My code is below.
public void showQuickProfileForm() {
Form f = new Form();
VideoComponent videoComponent = null;
try {
videoComponent = VideoComponent.createVideoPeer("capture://image");
} catch (IOException e) {
// e.printStackTrace();
try {
videoComponent = VideoComponent.createVideoPeer("capture://video");
} catch (IOException ex) {
// ex.printStackTrace();
}
}
videoComponent.setPreferredH((int) (Display.getInstance().getDisplayHeight() * 0.8));
videoComponent.setPreferredW(Display.getInstance().getDisplayWidth());
Player player = (Player) videoComponent.getNativePeer();
try {
player.realize();
player.start();
} catch (MediaException ex) {
ex.printStackTrace();
}
VideoControl videoControl = (VideoControl) player.getControl("VideoControl");
videoComponent.start();
f.addComponent(videoComponent);
f.addCommand(new Command("capture", 1));
f.show();
}
public void actionPerformed(ActionEvent evt) {
if (evt.getCommand().getId() == 1) {
// midlet.destroyApp(true);
Form d = new Form();
d.show();
}
}
Use this after initializing video control, change width and height as you see fit :
videoControl.setDisplaySize(width + 4, height - 25);

Audio on J2ME, I don't know where is wrong?

I want to do 2 task at same time:
Play an audio file.
Read raw data of it to do something
Here is my code:
String wavPath = "file:///" + currentPath + fileName;
FileConnection fc;
try {
fc = (FileConnection) Connector.open( wavPath );
if ( !fc.exists() ) {
throw new IOException( "File does not exists." );
}
InputStream is = fc.openInputStream();
// to do something with raw data as print samples of it
Player player = Manager.createPlayer( wavPath );
player.realize();
player.prefetch();
player.start();
} catch ( IOException e1 ) {
e1.printStackTrace();
}
But nothing run, audio file doesn't not run. If I remove line:
InputStream is = fc.openInputStream();
Audio file run very well. But I want to do 2 task at same time, i don't know how to do it. Anybody can help me ?
I have tried use 2 thread, but it still doesn't work, audio file run (thread 1) but thread 2 not run:
new Thread( new Runnable() {
public void run() {
try {
Manager.createPlayer( "file:///E:/" + fileName ).start();
} catch ( MediaException e ) {
e.printStackTrace();
} catch ( IOException e ) {
e.printStackTrace();
}
}
}).start();
new Thread( new Runnable() {
public void run() {
FileConnection fc;
try {
fc = (FileConnection) Connector.open( "file:///E:/" + fileName );
InputStream is = fc.openInputStream();
byte[] b = new byte[10];
int length = is.read( b, 0, 10 );
for ( int i = 0; i < length; i++ ) {
form.append( b[i] + "" );
}
} catch ( IOException e ) {
e.printStackTrace();
}
}
}).start();
why don't you use threading...
create a thread to play the wav file
and use another thread to do read a file...
refer here for further details on threading in J2ME
public class View_PlayMidlet extends MIDlet {
PlayerThread musicPlayer = new PlayerThread();
public void startApp() {
String fileName = "file://e:/abcd.wav";
musicPlayer.setPlayableFile(fileName);
FileConnection fc = null;
InputStream is = null;
String fileContent = null;
try {
fc = (FileConnection) Connector.open("file:///E:/" + fileName);
is = fc.openInputStream();
byte[] b = new byte[10];
int length = is.read(b, 0, 10);
fileContent = new String(b);
// display the content of fileContent variable in a form.
} catch (Exception e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException ex) {
}
}
if (fc != null) {
try {
fc.close();
} catch (IOException ex) {
}
}
}
// by this time the file is displayed & you can start playing the file.
Thread t = new Thread(musicPlayer);
t.start();
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
}
public class PlayerThread implements Runnable {
private String fileName;
private Player player;
public PlayerThread() {
}
public void run() {
try {
player = Manager.createPlayer(fileName);
player.prefetch();
player.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public void stopMusic() {
try {
player.stop();
} catch (Exception e) {
e.printStackTrace();
}
}
public void setPlayableFile(String fileName) {
this.fileName=fileName;
}
}
this would roughly be what you are looking for.
Your Player instances are garbage collected. Also, file access during playback will likely be 'implementation specific', meaning that it will work on some models and not others. So read the data first, copy it to another file etc, if you want something solid.
You can always go the DataSource-path too.

Categories