VideoRecorder.java
Upload User: liulanlin
Upload Date: 2017-12-08
Package Size: 1274k
Code Size: 13k
Category:

VOIP program

Development Platform:

Java

  1. /*
  2.  * VideoRecorder.java
  3.  * 
  4.  * Created on Mar 16, 2004
  5.  *
  6.  */
  7. package gov.nist.applet.phone.media.messaging;
  8. import java.io.File;
  9. import java.io.FileNotFoundException;
  10. import java.io.FileOutputStream;
  11. import java.io.IOException;
  12. import java.util.Vector;
  13. import javax.media.CaptureDeviceInfo;
  14. import javax.media.CaptureDeviceManager;
  15. import javax.media.ConfigureCompleteEvent;
  16. import javax.media.Controller;
  17. import javax.media.ControllerEvent;
  18. import javax.media.ControllerListener;
  19. import javax.media.EndOfMediaEvent;
  20. import javax.media.Format;
  21. import javax.media.IncompatibleSourceException;
  22. import javax.media.Manager;
  23. import javax.media.MediaLocator;
  24. import javax.media.MediaTimeSetEvent;
  25. import javax.media.PrefetchCompleteEvent;
  26. import javax.media.Processor;
  27. import javax.media.RealizeCompleteEvent;
  28. import javax.media.ResourceUnavailableEvent;
  29. import javax.media.SizeChangeEvent;
  30. import javax.media.StopAtTimeEvent;
  31. import javax.media.StopByRequestEvent;
  32. import javax.media.control.TrackControl;
  33. import javax.media.datasink.DataSinkErrorEvent;
  34. import javax.media.datasink.DataSinkEvent;
  35. import javax.media.datasink.DataSinkListener;
  36. import javax.media.datasink.EndOfStreamEvent;
  37. import javax.media.format.VideoFormat;
  38. import javax.media.protocol.ContentDescriptor;
  39. import javax.media.protocol.DataSource;
  40. import javax.media.protocol.FileTypeDescriptor;
  41. /**
  42.  * Class allowing one to record some audio in a buffer
  43.  * Play only MPEG_AUDIO and GSM audio data
  44.  * With some minor modifications can play RAW data also
  45.  * 
  46.  * @author Jean Deruelle <jean.deruelle@nist.gov>
  47.  *
  48.  * <a href="{@docRoot}/uncopyright.html">This code is in the public domain.</a>
  49.  */
  50. public class VideoRecorder implements ControllerListener, DataSinkListener, Runnable{
  51. Processor p;
  52. Object waitSync = new Object();
  53. boolean stateTransitionOK = true;
  54. static boolean monitorOn = false;
  55. private MediaLocator videoLocator=null;
  56. boolean bufferingDone = false;
  57. RawDataSourceHandler handler =null;
  58. Thread recorderThread=null;
  59. DataSource ds = null;
  60. /**
  61.  * get the devices for the audio capture and print their formats
  62.  */
  63. protected void initialize() {
  64. CaptureDeviceInfo videoCDI=null;
  65. Vector captureDevices=null;
  66. captureDevices= CaptureDeviceManager.getDeviceList(null);
  67. System.out.println("- number of capture devices: "+captureDevices.size() );
  68. CaptureDeviceInfo cdi=null;
  69. for (int i = 0; i < captureDevices.size(); i++) {
  70. cdi = (CaptureDeviceInfo) captureDevices.elementAt(i);
  71. Format[] formatArray=cdi.getFormats();
  72. for (int j = 0; j < formatArray.length; j++) {
  73. Format format=formatArray[j];
  74.    if (format instanceof VideoFormat) {
  75. if (videoCDI == null) {
  76. videoCDI=cdi;
  77. }
  78.    }    
  79. }
  80. }
  81. if(videoCDI!=null)
  82. videoLocator=videoCDI.getLocator();
  83. }
  84. /**
  85.  * Set the format of the tracks
  86.  * either to MPEG_AUDIO or GSM
  87.  */
  88. protected void setTrackFormat(){
  89. //Get the tracks from the processor
  90. TrackControl[] tracks = p.getTrackControls();
  91. // Do we have atleast one track?
  92. if (tracks == null || tracks.length < 1)
  93.   System.out.println("Couldn't find tracks in processor");
  94.  
  95. // Set the output content descriptor to GSM
  96. // This will limit the supported formats reported from
  97. // Track.getSupportedFormats to only valid AVI formats.
  98. //p.setContentDescriptor(new FileTypeDescriptor(FileTypeDescriptor.MPEG_AUDIO));
  99. p.setContentDescriptor(new ContentDescriptor(ContentDescriptor.RAW));
  100. Format supported[];
  101. Format chosen=null;
  102.   boolean atLeastOneTrack = false;
  103. // Program the tracks.
  104. for (int i = 0; i < tracks.length; i++) {
  105. Format format = tracks[i].getFormat();
  106. if (tracks[i].isEnabled()) {
  107. supported = tracks[i].getSupportedFormats();
  108. /*System.out.println("track : "+ i);
  109. for(int j=0;j<supported.length;j++)
  110. System.out.println("Supported format : "+supported[j].getEncoding());*/
  111. // We've set the output content to the GSM.            
  112. if (supported.length > 0) {
  113. for(int j=0;j<supported.length;j++){
  114. System.out.println("Supported format : "+supported[j].toString().toLowerCase());
  115.   if (supported[j] instanceof VideoFormat) {
  116. if(supported[j].toString().toLowerCase().indexOf("rgb")!=-1){
  117. chosen = supported[j];  
  118. break;
  119. }
  120. }
  121. }
  122. if(chosen!=null){
  123. tracks[i].setFormat(chosen);                
  124. System.err.println("Track " + i + " is set to transmit as:");
  125. System.err.println("  " + chosen);
  126. atLeastOneTrack = true;
  127. }
  128. else{
  129. System.err.println("Track " + i + " is set to transmit as nothing");
  130. }
  131. } else
  132. tracks[i].setEnabled(false);
  133. } else
  134. tracks[i].setEnabled(false);
  135. }
  136. }
  137. /**
  138.  * Given a DataSource, create a processor and hook up the output
  139.  * DataSource from the processor to a customed DataSink.
  140.  * @return false if something wrong happened
  141.  */
  142. protected boolean record() {
  143. // Create a DataSource given the media locator.
  144. try {
  145. ds = Manager.createDataSource(videoLocator);
  146. } catch (Exception e) {
  147. System.err.println("Cannot create DataSource from: " + videoLocator);
  148. return false;
  149. }
  150. try {
  151. p = Manager.createProcessor(ds);
  152. } catch (Exception e) {
  153. System.err.println("Failed to create a processor from the given DataSource: " + e);
  154. return false;
  155. }
  156. p.addControllerListener(this);
  157. // Put the Processor into configured state.
  158. p.configure();
  159. if (!waitForState(Processor.Configured)) {
  160. System.err.println("Failed to configure the processor.");
  161. return false;
  162. }
  163. setTrackFormat();
  164. /*ContentDescriptor[] descriptors = p.getSupportedContentDescriptors();
  165. for (int n = 0; n < descriptors.length; n++) {
  166. System.out.println("Desc: " + descriptors[n].toString());
  167. }*/
  168. // Get the raw output from the processor.
  169. //p.setContentDescriptor(new ContentDescriptor(ContentDescriptor.RAW));
  170. //p.setContentDescriptor(new FileTypeDescriptor(FileTypeDescriptor.MPEG_AUDIO));
  171. p.realize();
  172. if (!waitForState(Controller.Realized)) {
  173. System.err.println("Failed to realize the processor.");
  174. return false;
  175. }
  176. // Get the output DataSource from the processor and
  177. // hook it up to the RawDataSourceHandler.
  178. DataSource ods = p.getDataOutput();
  179. handler = new RawDataSourceHandler();
  180. try {
  181. handler.setSource(ods);
  182. } catch (IncompatibleSourceException e) {
  183. System.err.println("Cannot handle the output DataSource from the processor: " + ods);
  184. //return false;
  185. }
  186. System.err.println("Start datasource handler ");
  187. handler.addDataSinkListener(this);
  188. try{
  189. handler.setSource(ds);
  190. handler.start();
  191. }
  192. catch(IncompatibleSourceException ioe){
  193. ioe.printStackTrace();
  194. }
  195. System.err.println("Prefetch the processor ");
  196. // Prefetch the processor.
  197. p.prefetch();
  198. if (!waitForState(Controller.Prefetched)) {
  199. System.err.println("Failed to prefetch the processor.");
  200. return false;
  201. }
  202. // Start the processor.
  203. p.start();
  204. System.err.println("processor started");
  205. return true;
  206. }
  207. /**
  208.  * Block until file writing is done. 
  209.  */
  210. /*private boolean waitForFileDone(double duration) {
  211. synchronized (waitFileSync) {
  212. try {
  213. while (!bufferingDone) {
  214. if(p.getMediaTime().getSeconds() > duration)
  215. p.close();
  216. waitFileSync.wait(500);
  217. System.err.print(".");
  218. }
  219. } catch (Exception e) {}
  220. }
  221. bufferingDone=false;
  222. return true;
  223. }*/
  224. /**
  225.  * Block until the processor has transitioned to the given state.
  226.  * @param state - the state to wait for
  227.  * @return false if the transition failed.
  228.  */
  229. protected boolean waitForState(int state) {
  230. synchronized (waitSync) {
  231. try {
  232. while (p.getState() < state && stateTransitionOK)
  233. waitSync.wait();
  234. } catch (Exception e) {}
  235. }
  236. return stateTransitionOK;
  237. }
  238. /**
  239.  * Stop the voice recording
  240.  */
  241. public void stop(){
  242. p.stop();
  243. bufferingDone=true;
  244. }
  245. /**
  246.  * Start the voice recording
  247.  */
  248. public void start(){
  249. initialize();
  250. if(recorderThread==null){
  251. recorderThread=new Thread(this);
  252. recorderThread.setName("Voice Recorder Thread");
  253. }
  254. recorderThread.start();
  255. }
  256. /**
  257.  * the process of recording the voice
  258.  */
  259. public void run(){
  260. boolean succeeded=record();
  261. if(!succeeded)
  262. return;
  263. while(!bufferingDone){
  264. try{
  265. recorderThread.sleep(1);
  266. }
  267. catch(InterruptedException ie){
  268. ie.printStackTrace();
  269. }
  270. }
  271. try{
  272. Thread.sleep(100);
  273. }
  274. catch(InterruptedException ie){
  275. ie.printStackTrace();
  276. }
  277. //Clean up
  278. System.err.println("closing datasource" );
  279. try{
  280. ds.stop();
  281. }
  282. catch(IOException ioe){
  283. ioe.printStackTrace();
  284. }
  285. ds.disconnect();
  286. System.err.println("closing processor" );
  287. p.close();
  288. p.removeControllerListener(this);
  289. recorderThread=null;
  290. System.err.println("closing handler" );
  291. handler.close();
  292. System.err.println("...done Buffering.");
  293. bufferingDone=false;
  294. }
  295. /**
  296.  * Controller Listener Method.
  297.  * Allow one to know what happen on the recorder and the voice
  298.  * @param evt - event received 
  299.  */
  300. public void controllerUpdate(ControllerEvent evt) {
  301. //System.out.println("new Event received"+evt.getClass().getName());
  302. if (evt instanceof ConfigureCompleteEvent ||
  303. evt instanceof RealizeCompleteEvent ||
  304. evt instanceof PrefetchCompleteEvent) {
  305. synchronized (waitSync) {
  306. stateTransitionOK = true;
  307. waitSync.notifyAll();
  308. }
  309. } else if (evt instanceof ResourceUnavailableEvent) {
  310. synchronized (waitSync) {
  311. stateTransitionOK = false;
  312. waitSync.notifyAll();
  313. }
  314. } else if (evt instanceof EndOfMediaEvent) {
  315. System.err.println("closing datasource" );
  316. try{
  317. ds.stop();
  318. }
  319. catch(IOException ioe){
  320. ioe.printStackTrace();
  321. }
  322. ds.disconnect();
  323. System.err.println("closing controller");
  324. evt.getSourceController().close();
  325. //Clean up
  326. System.err.println("closing processor" );
  327. p.close();
  328. p.removeControllerListener(this);
  329. recorderThread=null;
  330. System.err.println("closing handler" );
  331. handler.close();
  332. System.err.println("...done Buffering.");
  333. bufferingDone=true;
  334. } else if (evt instanceof SizeChangeEvent) {
  335. }
  336. else if (evt instanceof MediaTimeSetEvent) {
  337. System.err.println("- mediaTime set: " + 
  338. ((MediaTimeSetEvent)evt).getMediaTime().getSeconds());
  339. } else if (evt instanceof StopAtTimeEvent) {
  340. System.err.println("- stop at time: " +
  341. ((StopAtTimeEvent)evt).getMediaTime().getSeconds());
  342. //Clean up
  343. System.err.println("closing datasource" );
  344. try{
  345. ds.stop();
  346. }
  347. catch(IOException ioe){
  348. ioe.printStackTrace();
  349. }
  350. ds.disconnect();
  351. System.err.println("closing controller");
  352. evt.getSourceController().close();
  353. System.err.println("closing processor" );
  354. p.close();
  355. p.removeControllerListener(this);
  356. recorderThread=null;
  357. System.err.println("closing handler" );
  358. handler.close();
  359. System.err.println("...done Buffering.");
  360. bufferingDone=true;
  361. }
  362. else if (evt instanceof StopByRequestEvent) {
  363. // Clean up
  364.   System.err.println("closing datasource" );
  365.   try{
  366.   ds.stop();
  367.   }
  368.   catch(IOException ioe){
  369.   ioe.printStackTrace();
  370.   }
  371.   ds.disconnect();
  372. System.err.println("closing controller");
  373. evt.getSourceController().close();
  374.    System.err.println("closing processor" );
  375.    p.close();
  376.    p.removeControllerListener(this);
  377.    recorderThread=null;
  378.    System.err.println("closing handler" );
  379.    handler.close();
  380.    System.err.println("...done Buffering.");
  381. }
  382. }
  383. /**
  384.  * Get the recorded voice buffer 
  385.  * @return the voice recorded in an array of bytes
  386.  */
  387. public byte[] getRecord(){
  388. return handler.getRecordBuffer();
  389. }
  390. /**
  391.  * DataSink Listener
  392.  * @param evt - event received  
  393.  */
  394. public void dataSinkUpdate(DataSinkEvent evt) {
  395. if (evt instanceof EndOfStreamEvent) {
  396. bufferingDone = true;
  397. //waitFileSync.notifyAll();
  398. System.err.println("All done!");
  399. evt.getSourceDataSink().close();
  400. //System.exit(0);
  401. }
  402. else if (evt instanceof DataSinkErrorEvent) {
  403. //synchronized (waitFileSync) {
  404. bufferingDone = true;
  405. evt.getSourceDataSink().close();
  406. //waitFileSync.notifyAll();
  407. //}
  408. }
  409. }
  410. /**
  411.  * Utility method to write a recorded voice buffer to a file
  412.  * @param data -  the recorded voice
  413.  */
  414. private static void writeBufferToFile(byte[] data){
  415. File f=new File("F://test.mov");
  416. FileOutputStream fos=null;
  417. try{
  418. fos=new FileOutputStream(f);
  419. }
  420. catch(FileNotFoundException fnfe){
  421. fnfe.printStackTrace();
  422. }
  423. try{
  424. fos.write(data);
  425. }
  426. catch(IOException ioe){
  427. ioe.printStackTrace();
  428. }
  429. }
  430. /**
  431.  * Main program
  432.  * @param args - 
  433.  */
  434. public static void main(String [] args) {
  435. VideoRecorder videoRecorder = new VideoRecorder();
  436. VideoPlayer videoPlayer=new VideoPlayer();
  437. //for(int i=0;i<2;i++){
  438. videoRecorder.start();
  439. try{
  440. Thread.sleep(5000);
  441. }
  442. catch(InterruptedException ie){
  443. ie.printStackTrace();
  444. }
  445. videoRecorder.stop();
  446. videoPlayer.initialize(videoRecorder.getRecord());
  447. videoPlayer.play();
  448. try{
  449. Thread.sleep(5000);
  450. }
  451. catch(InterruptedException ie){
  452. ie.printStackTrace();
  453. }
  454. //}
  455. writeBufferToFile(videoRecorder.getRecord());
  456. }
  457. }