首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

JMF视频音频通讯( 图+源码 )

2012-11-01 
JMF视频音频通信( 图+源码 )?最近由于做山寨QQ视频聊天的需要,做了一个视频通信窗口组件。现在分享一下供大

JMF视频音频通信( 图+源码 )


?最近由于做山寨QQ视频聊天的需要,做了一个视频通信窗口组件。现在分享一下供大家学习……

??原创文章,转载请标明出处!谢谢!

工程文件下载地址:http://download.csdn.net/source/3378150

?本文地址: http://mzhx-com.iteye.com/blog/1098698

? 效果图如下:

?

?

JMF视频音频通讯( 图+源码 )

?

三个类 源代码如下:

?

package vidioPlay;import java.awt.Dimension;import java.io.IOException;import java.net.InetAddress;import java.util.Vector;import javax.media.CaptureDeviceInfo;import javax.media.Codec;import javax.media.Control;import javax.media.Controller;import javax.media.ControllerClosedEvent;import javax.media.ControllerEvent;import javax.media.ControllerListener;import javax.media.Format;import javax.media.IncompatibleSourceException;import javax.media.Manager;import javax.media.MediaLocator;import javax.media.NoProcessorException;import javax.media.Owned;import javax.media.Player;import javax.media.Processor;import javax.media.cdm.CaptureDeviceManager;import javax.media.control.QualityControl;import javax.media.control.TrackControl;import javax.media.format.AudioFormat;import javax.media.format.VideoFormat;import javax.media.protocol.ContentDescriptor;import javax.media.protocol.DataSource;import javax.media.protocol.PushBufferDataSource;import javax.media.protocol.PushBufferStream;import javax.media.protocol.SourceCloneable;import javax.media.rtp.RTPManager;import javax.media.rtp.SendStream;import javax.media.rtp.SessionAddress;import javax.media.rtp.rtcp.SourceDescription;import javax.swing.JFrame;public class MediaTransmit {private String ipAddress;private int portBase;private MediaLocator audioLocator = null, vedioLocator = null;private Processor audioProcessor = null;private Processor videoProcessor = null;private DataSource audioDataLocal = null, videoDataLocal = null;private DataSource audioDataOutput = null, videoDataOutput = null;private RTPManager rtpMgrs[];private DataSource mediaData = null;private DataSource dataLocalClone = null;private PlayPane playFrame;public MediaTransmit(String ipAddress, String pb) {this.ipAddress = ipAddress;Integer integer = Integer.valueOf(pb);if (integer != null) {this.portBase = integer.intValue();}// /////////////////////////////////////////////playFrame = new PlayPane();JFrame jf = new JFrame("视频实例");jf.add(playFrame);jf.pack();jf.setLocationRelativeTo(null);jf.setDefaultCloseOperation(3);jf.setVisible(true);// ////////////////////////////////////////////Vector<CaptureDeviceInfo> video = CaptureDeviceManager.getDeviceList(new VideoFormat(null));Vector<CaptureDeviceInfo> audio = CaptureDeviceManager.getDeviceList(new AudioFormat(AudioFormat.LINEAR, 44100, 16, 2));// MediaLocator mediaLocator = new// MediaLocator("file:/C:/纯音乐 - 忧伤还是快乐.mp3");if (audio != null && audio.size() > 0) {audioLocator = ((CaptureDeviceInfo) audio.get(0)).getLocator();if ((audioProcessor = createProcessor(audioLocator)) != null) {audioDataLocal = mediaData;audioDataOutput = audioProcessor.getDataOutput();}} else {System.out.println("******错误:没有检测到您的音频采集设备!!!");}// /////////////////////////////////////////////////////////if (video != null && video.size() > 0) {vedioLocator = ((CaptureDeviceInfo) video.get(0)).getLocator();if ((videoProcessor = createProcessor(vedioLocator)) != null) {videoDataLocal = mediaData;videoDataOutput = videoProcessor.getDataOutput();}} else {System.out.println("******错误:没有检测到您的视频设备!!!");}// /////////////////////////////////////////////////////////final DataSource[] dataSources = new DataSource[2];dataSources[0] = audioDataLocal;dataSources[1] = videoDataLocal;try {DataSource dsLocal = Manager.createMergingDataSource(dataSources);playFrame.localPlay(dsLocal);} catch (IncompatibleSourceException e) {e.printStackTrace();return;}// ////////////////////////////////////////////////远程传输dataSources[1] = audioDataOutput;dataSources[0] = videoDataOutput;try {DataSource dsoutput = Manager.createMergingDataSource(dataSources);createTransmitter(dsoutput);} catch (IncompatibleSourceException e) {e.printStackTrace();return;}audioProcessor.start();videoProcessor.start();}private Processor createProcessor(MediaLocator locator) {Processor processor = null;if (locator == null)return null;// 通过设备定位器得到数据源,try {mediaData = Manager.createDataSource(locator);// 创建可克隆数据源mediaData = Manager.createCloneableDataSource(mediaData);// 克隆数据源,用于传输到远程dataLocalClone = ((SourceCloneable) mediaData).createClone();} catch (Exception e) {e.printStackTrace();return null;}try {processor = javax.media.Manager.createProcessor(dataLocalClone);} catch (NoProcessorException npe) {npe.printStackTrace();return null;} catch (IOException ioe) {return null;}boolean result = waitForState(processor, Processor.Configured);if (result == false)return null;TrackControl[] tracks = processor.getTrackControls();if (tracks == null || tracks.length < 1)return null;ContentDescriptor cd = new ContentDescriptor(ContentDescriptor.RAW_RTP);processor.setContentDescriptor(cd);Format supportedFormats[];Format chosen;boolean atLeastOneTrack = false;for (int i = 0; i < tracks.length; i++) {if (tracks[i].isEnabled()) {supportedFormats = tracks[i].getSupportedFormats();if (supportedFormats.length > 0) {if (supportedFormats[0] instanceof VideoFormat) {chosen = checkForVideoSizes(tracks[i].getFormat(),supportedFormats[0]);} elsechosen = supportedFormats[0];tracks[i].setFormat(chosen);System.err.println("Track " + i + " is set to transmit as:");System.err.println("  " + chosen);atLeastOneTrack = true;} elsetracks[i].setEnabled(false);} elsetracks[i].setEnabled(false);}if (!atLeastOneTrack)return null;result = waitForState(processor, Controller.Realized);if (result == false)return null;setJPEGQuality(processor, 0.5f);return processor;}private String createTransmitter(DataSource dataOutput) {PushBufferDataSource pbds = (PushBufferDataSource) dataOutput;PushBufferStream pbss[] = pbds.getStreams();System.out.println("pbss.length:" + pbss.length);rtpMgrs = new RTPManager[pbss.length];SendStream sendStream;int port;// SourceDescription srcDesList[];for (int i = 0; i < pbss.length; i++) {try {rtpMgrs[i] = RTPManager.newInstance();port = portBase + 2 * i;SessionAddress localAddr = new SessionAddress(InetAddress.getLocalHost(), port);SessionAddress destAddr = new SessionAddress(InetAddress.getByName(ipAddress), port);rtpMgrs[i].initialize(localAddr);rtpMgrs[i].addTarget(destAddr);System.out.println("Created RTP session: "+ InetAddress.getLocalHost() + " " + port);sendStream = rtpMgrs[i].createSendStream(dataOutput, i);sendStream.start();} catch (Exception e) {e.printStackTrace();return e.getMessage();}}return null;}Format checkForVideoSizes(Format original, Format supported) {int width, height;Dimension size = ((VideoFormat) original).getSize();Format jpegFmt = new Format(VideoFormat.JPEG_RTP);Format h263Fmt = new Format(VideoFormat.H263_RTP);if (supported.matches(jpegFmt)) {width = (size.width % 8 == 0 ? size.width: (int) (size.width / 8) * 8);height = (size.height % 8 == 0 ? size.height: (int) (size.height / 8) * 8);} else if (supported.matches(h263Fmt)) {if (size.width < 128) {width = 128;height = 96;} else if (size.width < 176) {width = 176;height = 144;} else {width = 352;height = 288;}} else {return supported;}return (new VideoFormat(null, new Dimension(width, height),Format.NOT_SPECIFIED, null, Format.NOT_SPECIFIED)).intersects(supported);}void setJPEGQuality(Player p, float val) {Control cs[] = p.getControls();QualityControl qc = null;VideoFormat jpegFmt = new VideoFormat(VideoFormat.JPEG);for (int i = 0; i < cs.length; i++) {if (cs[i] instanceof QualityControl && cs[i] instanceof Owned) {Object owner = ((Owned) cs[i]).getOwner();if (owner instanceof Codec) {Format fmts[] = ((Codec) owner).getSupportedOutputFormats(null);for (int j = 0; j < fmts.length; j++) {if (fmts[j].matches(jpegFmt)) {qc = (QualityControl) cs[i];qc.setQuality(val);System.err.println("- Setting quality to " + val+ " on " + qc);break;}}}if (qc != null)break;}}}private Integer stateLock = new Integer(0);private boolean failed = false;Integer getStateLock() {return stateLock;}void setFailed() {failed = true;}private synchronized boolean waitForState(Processor p, int state) {p.addControllerListener(new StateListener());failed = false;if (state == Processor.Configured) {p.configure();} else if (state == Processor.Realized) {p.realize();}while (p.getState() < state && !failed) {synchronized (getStateLock()) {try {getStateLock().wait();} catch (InterruptedException ie) {return false;}}}if (failed)return false;elsereturn true;}class StateListener implements ControllerListener {public void controllerUpdate(ControllerEvent ce) {if (ce instanceof ControllerClosedEvent)setFailed();if (ce instanceof ControllerEvent) {synchronized (getStateLock()) {getStateLock().notifyAll();}}}}public static void main(String[] args) {String[] strs = { "localhost", "9994" };new MediaTransmit(strs[0], strs[1]);}}

?

?

?

package vidioPlay;import java.awt.BorderLayout;import java.awt.Component;import java.awt.Dimension;import java.awt.Panel;import java.net.InetAddress;import java.util.Vector;import javax.media.ControllerErrorEvent;import javax.media.ControllerEvent;import javax.media.ControllerListener;import javax.media.Player;import javax.media.RealizeCompleteEvent;import javax.media.bean.playerbean.MediaPlayer;import javax.media.control.BufferControl;import javax.media.format.FormatChangeEvent;import javax.media.protocol.DataSource;import javax.media.rtp.Participant;import javax.media.rtp.RTPControl;import javax.media.rtp.RTPManager;import javax.media.rtp.ReceiveStream;import javax.media.rtp.ReceiveStreamListener;import javax.media.rtp.SessionListener;import javax.media.rtp.event.ByeEvent;import javax.media.rtp.event.NewParticipantEvent;import javax.media.rtp.event.NewReceiveStreamEvent;import javax.media.rtp.event.ReceiveStreamEvent;import javax.media.rtp.event.RemotePayloadChangeEvent;import javax.media.rtp.event.SessionEvent;import javax.media.rtp.event.StreamMappedEvent;import javax.swing.JFrame;import net.sf.fmj.media.rtp.RTPSocketAdapter;public class MediaReceive implements ReceiveStreamListener, SessionListener,ControllerListener {String sessions[] = null;RTPManager mgrs[] = null;boolean dataReceived = false;Object dataSync = new Object();private PlayPane playFrame;public MediaReceive(String sessions[]) {this.sessions = sessions;}protected void initialize() {playFrame = new PlayPane();JFrame jf = new JFrame("视频实例");jf.add(playFrame);jf.pack();jf.setLocationRelativeTo(null);jf.setDefaultCloseOperation(3);jf.setVisible(true);try {// 每一个session对应一个RTPManagermgrs = new RTPManager[sessions.length];// 创建播放窗口的向量vectorSessionLabel session = null;// Open the RTP sessions.// 针对每一个会话对象进行ip、port和ttl的解析for (int i = 0; i < sessions.length; i++) {// Parse the session addresses.// 进行会话对象的解析,得到ip、port和ttltry {session = new SessionLabel(sessions[i]);} catch (IllegalArgumentException e) {System.err.println("Failed to parse the session address given: "+ sessions[i]);// return false;}System.err.println("  - Open RTP session for: addr: "+ session.addr + " port: " + session.port + " ttl: "+ session.ttl);// 这对本条会话对象创建RTPManagermgrs[i] = (RTPManager) RTPManager.newInstance();mgrs[i].addSessionListener(this);mgrs[i].addReceiveStreamListener(this);// Initialize the RTPManager with the RTPSocketAdapter// 将本机ip和端口号加入RTP会话管理System.out.println("session.addr:" + session.addr);mgrs[i].initialize(new RTPSocketAdapter(InetAddress.getByName(session.addr), session.port, session.ttl));BufferControl bc = (BufferControl) mgrs[i].getControl("javax.media.control.BufferControl");if (bc != null)bc.setBufferLength(350);}} catch (Exception e) {e.printStackTrace();}}/** * Close the players and the session managers. */protected void close() {// close the RTP session.for (int i = 0; i < mgrs.length; i++) {if (mgrs[i] != null) {mgrs[i].removeTargets("Closing session from AVReceive3");mgrs[i].dispose();mgrs[i] = null;}}}/** * SessionListener. */@SuppressWarnings("deprecation")public synchronized void update(SessionEvent evt) {if (evt instanceof NewParticipantEvent) {Participant p = ((NewParticipantEvent) evt).getParticipant();System.err.println("  - A new participant had just joined: " + p);}}/** * ReceiveStreamListener */public synchronized void update(ReceiveStreamEvent evt) {RTPManager mgr = (RTPManager) evt.getSource();Participant participant = evt.getParticipant(); // could be null.ReceiveStream stream = evt.getReceiveStream(); // could be null.if (evt instanceof RemotePayloadChangeEvent) {System.err.println("  - Received an RTP PayloadChangeEvent.");System.err.println("Sorry, cannot handle payload change.");// System.exit(0);}else if (evt instanceof NewReceiveStreamEvent) {System.out.println("evt instanceof NewReceiveStreamEvent");try {stream = ((NewReceiveStreamEvent) evt).getReceiveStream();final DataSource data = stream.getDataSource();// Find out the formats.RTPControl ctl = (RTPControl) data.getControl("javax.media.rtp.RTPControl");if (ctl != null) {System.err.println("  - Recevied new RTP stream: "+ ctl.getFormat());} elseSystem.err.println("  - Recevied new RTP stream");if (participant == null)System.err.println("      The sender of this stream had yet to be identified.");else {System.err.println("      The stream comes from: "+ participant.getCNAME());}// create a player by passing datasource to the Media Managernew Thread() {public void run() {playFrame.remotePlay(data);}}.start();// Player p = javax.media.Manager.createPlayer(data);// if (p == null)// return;//// p.addControllerListener(this);// p.realize();// PlayerWindow pw = new PlayerWindow(p, stream);// playerWindows.addElement(pw);// Notify intialize() that a new stream had arrived.synchronized (dataSync) {dataReceived = true;dataSync.notifyAll();}} catch (Exception e) {System.err.println("NewReceiveStreamEvent exception "+ e.getMessage());return;}}else if (evt instanceof StreamMappedEvent) {System.out.println("evt instanceof StreamMappedEvent");stream = ((StreamMappedEvent) evt).getReceiveStream();if (stream != null && stream.getDataSource() != null) {DataSource ds = stream.getDataSource();// Find out the formats.RTPControl ctl = (RTPControl) ds.getControl("javax.media.rtp.RTPControl");System.err.println("  - The previously unidentified stream ");if (ctl != null)System.err.println("      " + ctl.getFormat());System.err.println("      had now been identified as sent by: "+ participant.getCNAME());System.out.println("ds == null" + (ds == null));}}else if (evt instanceof ByeEvent) {System.err.println("  - Got "bye" from: "+ participant.getCNAME());}}/** * ControllerListener for the Players. */public synchronized void controllerUpdate(ControllerEvent ce) {Player p = (Player) ce.getSourceController();if (p == null)return;}/** * A utility class to parse the session addresses. */class SessionLabel {public String addr = null;public int port;public int ttl = 1;SessionLabel(String session) throws IllegalArgumentException {int off;String portStr = null, ttlStr = null;if (session != null && session.length() > 0) {while (session.length() > 1 && session.charAt(0) == '/') {session = session.substring(1);}off = session.indexOf('/');if (off == -1) {if (!session.equals(""))addr = session;} else {addr = session.substring(0, off);session = session.substring(off + 1);off = session.indexOf('/');if (off == -1) {if (!session.equals(""))portStr = session;} else {portStr = session.substring(0, off);session = session.substring(off + 1);off = session.indexOf('/');if (off == -1) {if (!session.equals(""))ttlStr = session;} else {ttlStr = session.substring(0, off);}}}}if (addr == null)throw new IllegalArgumentException();if (portStr != null) {try {Integer integer = Integer.valueOf(portStr);if (integer != null)port = integer.intValue();} catch (Throwable t) {throw new IllegalArgumentException();}} elsethrow new IllegalArgumentException();if (ttlStr != null) {try {Integer integer = Integer.valueOf(ttlStr);if (integer != null)ttl = integer.intValue();} catch (Throwable t) {throw new IllegalArgumentException();}}}}public static void main(String argv[]) {String[] strs = { "125.221.165.126/9994", "125.221.165.126/9996" };MediaReceive avReceive = new MediaReceive(strs);avReceive.initialize();}}

?

?

?

package vidioPlay;import java.awt.BorderLayout;import java.awt.Color;import java.awt.Component;import java.awt.Dimension;import java.awt.FlowLayout;import java.awt.Graphics;import java.awt.Rectangle;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.IOException;import javax.media.ControllerEvent;import javax.media.ControllerListener;import javax.media.DataSink;import javax.media.NoPlayerException;import javax.media.Player;import javax.media.Processor;import javax.media.protocol.DataSource;import javax.swing.ImageIcon;import javax.swing.JButton;import javax.swing.JPanel;public class PlayPane extends JPanel {private ImageIcon videoReqIcon = new ImageIcon("videoReq.jpg");private ImageIcon VideolocalIcon = new ImageIcon("localVideo.jpg");private boolean isViewBigPlaying = false;private boolean isViewSmallPlaying = false;private JPanel viewBigPane;private JPanel viewSmallPane;private JPanel controlPane;private JButton closeButton;private boolean localPlay = false;private boolean remotePlay = false;private DataSource localData;private DataSource remoteData;private boolean isViewRun = true;private boolean isShow = true;//private Player localPlayer = null;private Player remotePlayer = null;//private Processor videotapeProcessor = null;private Player videotapePlayer = null;private DataSink videotapeFileWriter;public PlayPane() {this.setLayout(new BorderLayout());// 视图面板viewBigPane = new JPanel() {public void paintComponent(Graphics g) {super.paintComponent(g);if (!isViewBigPlaying) {g.drawImage(videoReqIcon.getImage(), 1, 1,videoReqIcon.getIconWidth(),videoReqIcon.getIconHeight(), null);g.drawRect(getSmallPlayRec().x - 1,getSmallPlayRec().y - 1,getSmallPlayRec().width + 1,getSmallPlayRec().height + 1);} else {}}};viewBigPane.setBackground(Color.black);this.add(viewBigPane, BorderLayout.CENTER);viewBigPane.setLayout(null);// ///////////////////////////////viewSmallPane = new JPanel() {public void paintComponent(Graphics g) {super.paintComponent(g);if (!isViewSmallPlaying) {g.drawImage(VideolocalIcon.getImage(), 0, 0, null);} else {}}};viewSmallPane.setBounds(getSmallPlayRec());viewBigPane.add(viewSmallPane);viewSmallPane.setLayout(null);// 控制面板组件closeButton = new JButton("挂断");controlPane = new JPanel();controlPane.setLayout(new FlowLayout(FlowLayout.RIGHT, 0, 0));controlPane.add(closeButton);this.add(controlPane, BorderLayout.SOUTH);closeButton.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {if (localPlayer != null) {localPlayer.stop();}if (remotePlayer != null) {remotePlayer.stop();}if (videotapePlayer != null) {videotapePlayer.stop();}if (videotapeProcessor != null) {videotapeProcessor.stop();}if (videotapeFileWriter != null) {try {videotapeFileWriter.stop();videotapeFileWriter.close();} catch (IOException e1) {}}}});// this.setMinimumSize(new Dimension(videoReqIcon.getIconWidth()+2,// 241));// this.setPreferredSize(new Dimension(videoReqIcon.getIconWidth()+2,// 241));}public Dimension getMinimumSize() {System.out.println("controlPane.getHeight():" + controlPane.getHeight());return new Dimension(videoReqIcon.getIconWidth() + 2,videoReqIcon.getIconHeight() + controlPane.getHeight());}public Dimension getPreferredSize() {System.out.println("controlPane.getHeight():" + controlPane.getHeight());return new Dimension(videoReqIcon.getIconWidth() + 2,videoReqIcon.getIconHeight()+ controlPane.getPreferredSize().height);}public void localPlay(DataSource dataSource) {this.setLocalData(dataSource);try {localPlayer = javax.media.Manager.createPlayer(dataSource);localPlayer.addControllerListener(new ControllerListener() {public void controllerUpdate(ControllerEvent e) {if (e instanceof javax.media.RealizeCompleteEvent) {Component comp = null;comp = localPlayer.getVisualComponent();if (comp != null) {// 将可视容器加到窗体上comp.setBounds(0, 0, VideolocalIcon.getIconWidth(),VideolocalIcon.getIconHeight());viewSmallPane.add(comp);}viewBigPane.validate();}}});localPlayer.start();localPlay = true;} catch (NoPlayerException e1) {e1.printStackTrace();} catch (IOException e1) {e1.printStackTrace();}}private Rectangle getSmallPlayRec() {int bigShowWidth = videoReqIcon.getIconWidth();int bigShowHeight = videoReqIcon.getIconHeight();int smallShowWidth = VideolocalIcon.getIconWidth();int smallShowHeight = VideolocalIcon.getIconHeight();return new Rectangle(bigShowWidth - smallShowWidth - 2, bigShowHeight- smallShowHeight - 2, smallShowWidth, smallShowHeight);}public void remotePlay(DataSource dataSource) {this.setLocalData(dataSource);remotePlay = true;try {remotePlayer = javax.media.Manager.createPlayer(dataSource);remotePlayer.addControllerListener(new ControllerListener() {public void controllerUpdate(ControllerEvent e) {if (e instanceof javax.media.RealizeCompleteEvent) {Component comp;if ((comp = remotePlayer.getVisualComponent()) != null) {// 将可视容器加到窗体上comp.setBounds(1, 1, videoReqIcon.getIconWidth(),videoReqIcon.getIconHeight());viewBigPane.add(comp);}viewBigPane.validate();}}});remotePlayer.start();remotePlay = true;} catch (NoPlayerException e1) {e1.printStackTrace();} catch (IOException e1) {e1.printStackTrace();}}public void closeViewUI() {isShow = false;}public boolean isViewRunning() {return isViewRun;}public boolean isShowing() {return isShow;}public void localReady() {localPlay = true;}public void remoteReady() {remotePlay = true;}public boolean isRemotePlay() {return remotePlay;}public void setRemotePlay(boolean remotePlay) {this.remotePlay = remotePlay;}public DataSource getRemoteData() {return remoteData;}public void setRemoteData(DataSource remoteData) {this.remoteData = remoteData;}public boolean isLocalPlay() {return localPlay;}public void setLocalPlay(boolean localPlay) {this.localPlay = localPlay;}public DataSource getLocalData() {return localData;}public void setLocalData(DataSource localData) {this.localData = localData;}}

?

?

之后操作如下:

1、安装JMF软件(如果不想安装,就请阅读我转载一篇文章):
JMF视频音频通讯( 图+源码 )

2、新建工程将源代码加入工程src下

3、导入第三方包jmf.jar,和fmj.jar(如果网上找不到,请加入该群83945749)

4、运行的时候先运行MediaTransmit类,后运行MediaReceive类
?

?


看背后那门很像寝室的门吧。。。 视频我用的是手机摄像头,就算了,音频用的耳机麦克风怎么也不行啊?

热点排行