知识大全 技术交流:QuickTime流媒体和Java(图)

Posted 文件

篇首语:人格成熟的重要标志:宽容、忍让、和善。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 技术交流:QuickTime流媒体和Java(图)相关的知识,希望对你有一定的参考价值。

技术交流:QuickTime流媒体和Java(图)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  这并不是即将问世的QuickTime for Java book一书的摘录 虽然我希望是的     你看 问题是 在QTJ世界中大多数的我们都一直假定QTJ中的流媒体API已经损坏 我并不是想为此事而掩盖什么 好的 我继续来通过各种各样的人通过不同的技术进行工作的掩盖获取去这样做 但是我不想再来一次 此外 流媒体冲突的情况似乎特别的糟糕 没有人能得到它的演示代码工作方式――this post to the quicktime java list 是令许多用户对获取苹果公司的AudioBroadcaster 和DrawableBroadcaster 演示工作方式绝望的典型 让事情更糟糕 演示之一依靠一个在QTJ 版本中作为退回到原始的GUI提供的已经被取消的GUI预览组件类 提供组件只对Movies MovieControllers 和GraphicsImporters 而不是流式的Presentations 视频捕捉 或者某些图形美好得像来自多种资源 合成 制作 所以 官方给出的演示它首先看起来是不会工作 和现在的关键类有冲突(如果在Java 中运行会抛出RuntimeExceptions异常) 预测实际的流式内容和QTJ 看上去会非常糟糕     令我欣喜 甚至是有点吃惊的是 有报道称流媒体能够在QTJ 中工作 在本文章中 我将介绍通过QTJ实现简单的网络广播的基础     需求    QuickTime的流媒体API 在Java中由只可在Mac OS(Classic和OS X)中运行的包quicktime streaming声明 在QTJ中存在Windows版本的类 但是它们却不能工作 但是 你可以使用Windows版本的QuickTime作为流媒体的客户端 如果在Java中运行并不是关键的 你可获取Darwin Streaming Server 一个开源项目可在Windows Server 和 Server上运行如同在Solaris 和 Red Hat Linux 上一样     使用QuickTime流媒体最简单的事情就是我在此说明的生动内容 你需要至少一个音频输入设备 如一个内置的麦克风或者一个耳机 当然 拥有一个QuickTime支持的摄像机 如一个iSight 将会更让人印象深刻      Streaming 是什么 不是什么    给出了术语 流 的含义并不容易明确术语 Streaming 的正确含义 例如 QuickTime长期支持一种 快速启动 的特征――如果QuickTime明确拥有足够的开始播放的资源并且不会用完目前下载速率下的资源一段录像能开始播放――那是一些用户将Streaming 的一种形式弄错了 自然的 这有它自己的优势 容易创建并且确保了所有的包都到达了客户端 但是真正的 Streaming 换句话说 Streaming 符合Internet工程工作小组(IETF)的标准 这是一个完全不同的问题 直到QuickTime 才被支持 并且直到QTJ 才支持Java     Streaming 的形式允许服务器控制传输 但很难在实时中保证最优化运行 客户端未下载潜在的大文件 这样的方法是独特的便利的直接广播 事实上 QuickTime的流媒体使用两种 实时 的流媒体传输协议 实时传输协议(RTP)来传输媒体数据包 实时流协议(RTSP)用于控制信息 RTP使用潜在的有损UDP连接 所以所有的人都有意的忍耐再传输期间的包的丢失 这就意味着客户端需要友好的操作未获取所有数据的视频帧或者音频例子 更好的方法是通过基于TCP/IP的连接 它可以使用不确定的重试(也会因此需要一个不确定的时间)来获取丢失的包      Presentation和SDP文件    在QuickTime中 流媒体传输等同一个电影――一个电影可以有音轨和视轨 一个元数据的聚集将它们全都联系在一起 此表示会将一些多种的音频和视频流的元数据联系起来 音频和视频你非常喜欢的流媒体种类也是值得关注的 自从某些其他的媒体类型(sprites Flash内容)被QuickTime支持后并没有操作好失去的包 并不适合作为流媒体传播     你可能被建议去建立一个流媒体 你会需要创建一个Presentation 并开始它 但是现在呢?最普遍的这样做的方法是创建一个会话描述协议(SDP)文件 将其放入静态工厂方法Presentation fromFile() SDP文件以一种适当的简单的文本格式 由RFC 和several updates所定义 我发现这些都是早期的理论而不是实际操作 但是稍后让我们担心的是执行详细信息 这是一个被一些Apple的流媒体使用的例子 在Tim Monroe的QuickTime Toolkit Volume Two中     v=   c=IN IP / /   m=audio RTP/AVP   m=video RTP/AVP   a=rtpmap: H     以下是每一行的解释     ·v= 这是SDP的版本号 在这里版本号是 表示在SDP中没有次要的号码   ·c=IN IP / / 这是提供在描述中使用的连接的信息 IN IP 表示是一个IPv 的网络地址 是地址(注意这是一个多点传输地址 所有许多的客户端能连接到广播) 是存在时间 是临近使用的多点传输地址的数量   ·m=audio RTP/AVP m=这一行定义了用于广播的流媒体 在这里明显的是audio 发送经由到RTP到端口 在简单的QCELP音频中定义了有效负载类型 这些在RFC 中定义了   ·m=video RTP/AVP 这一媒体行定义了一个video媒体流 由RTP传输到端口 有效负载类型为 所以使用 表示在原始的RFC中视频格式没有给出负载类型 在SDP中替换它会被映射到一个众所周知的常量中   ·a=rtpmap: H 这个完成键入在前一行指出的动态负载 使用此类型 你会使用一个在 和 之间的值(本例中是 ) 然后用一个字符串命名此负载类型(H )     这当然好 但是当在我的例程序中使用它的时候 我只获得了一个视频流却没有声音 所以 我使用了一个很不同的SDP 最初在QTJ的DrawableBroadcaster演示中出现 是的 他们不赞同这么做     m=audio RTP/AVP   c=IN IP   a=rtpmap: x qt  m=video RTP/AVP   a=rtpmap: x qt    这里最大的不同就是音频和视频都使用了相同的动态负载映射 这并不是针对一个真正的编码器 而是一般的x qt 在这里胜利的是你能在运行时间上挑选任一QuickTime的音频和视频编码器 而不是在SDP文件中强迫导致 底侧是这些可以不是由非QuickTime客户端可分析的 反之使用十分标准的和/或者旧的编码器并且在SDP中指定他们使它更像其他的客户端(Real JMF等)能够操作你的系统     这就是你的SDP文件 现在不要加入一个Presentation      创建Presentation    我们的流媒体服务器程序调用LittleBroadcast 这并没有多少代码 只有不过 行 在本文中 我将一步一步的进行 解释一般的部分 但提供其全部的清单 在后面的Resources章节中有可用到一个 tar gz文件 连同SDP文件和一个Ant构建文件     package mac invalidname qtjstreaming;import quicktime *;  import quicktime std *;  import quicktime util *;  import quicktime qd *;  import quicktime io *;  import quicktime streaming *;  import quicktime app time *;  import java io *;import java awt *;  import java awt event *;  public class LittleBroadcast extends Tasking implements ActionListener     这是一长串典型的引入QuickTime 包括了使用其QDGraphics来提供一个摄像机画面以外的图形界面的qd 读取SDP文件的io 用于流媒体API的streaming 以及获得给予Presentation运行时间的有效任务的time 最后一点 注意该类扩展直Tasking――提供周期性调用的task() 本应用程序中 它用于不断的调用Presentation的idle()方法 并使其循环工作 你在本书中学习到也就是Movies所需要的 但是此任务几乎一直都自动的为你所操作 使用Presentation并不好运 (或者为此事而捕获 但有些离开本主题了 )    boolean broadcasting = false;  public static final int BROADCAST_WIDTH = ;  public static final int BROADCAST_HEIGHT = ;  Button startStopButton;  Button configButton;  Presentation pres;  int presenterTimeScale = ;    这些是服务器的实例变量 是一个用于指定当开始/停止按钮按下的时候做什么的标记 下面是一对广播视频大小的常量 紧跟着是服务器GUI的按钮 最后是一个Presentation对象 以及它的时间尺度 (媒体的保持时间系统 一个 的时间尺度表示一秒种里有 个单位 也是QuickTime中默认的 )    public static void main (String[] args)   System out println ( main );  try   QTSession open();  new LittleBroadcast();   catch (QTException qte)   qte printStackTrace();        在这个main中并没有什么独特的地方 我投入了所有的精力在构造函数上以防止为那些我需要的实例创建一个内部类 如果你扩展本代码 你可能会发现这很有用     public LittleBroadcast() throws QTException   System out println ( LittleBroadcast constructor );  QTFile file = new QTFile (new File ( little sdp ));  try   MediaParams mediaParams = new MediaParams();  mediaParams setWidth (BROADCAST_WIDTH);  mediaParams setHeight (BROADCAST_HEIGHT);  QDGraphics myGWorld =  new QDGraphics (new QDRect (  BROADCAST_WIDTH BROADCAST_HEIGHT));  mediaParams setGWorld (myGWorld);  PresParams presParams =  new PresParams( presenterTimeScale   QTSConstants kQTSSendMediaFlag |  QTSConstants kQTSAutoModeFlag |  QTSConstants kQTSDontShowStatusFlag   mediaParams );  pres = Presentation fromFile(file presParams );    构造函数的第一事是装载名为little sdp的SDP文件 但这并不是所有的都需要创建Presentation ――在调用Presentation fromFile()的时候需要服务器应用程序设置一些必要的参数 首先 你要创建一个MediaParams对象 这样你能设置视频的高度和宽度 您必须做的其它重要事是提供照相机一个图形界面 由QDGraphics创建MediaParams设置 是的 名字是古怪的 因为QTJ 设计员想注重与AWT Graphics对象的相似性 但得到或设置这样的对象的用途的所有方法是使用其本地API名字 GWorld 最后 你为所有的Presentation创建一个PresParams来设置参数 这采取一个有些任意的时标 一些算术上的行为标记彼此OR ed 以及MediaParams 可能的行为标记 都被定义在QTSConstants 包括:    ·KQTSAutoModeFlag: 都使用默认值 最重要地 这些使用默认值Sourcer Presentation的来源 是从各种各样的输入装置执行获取的SequenceGrabber 它还可能播放一个在磁盘上或是任意目录下的的QuickTime 文件; 稍后我将探讨这些问题     ·KQTDontShowStatusFlag: 不要创建一个会导致连接数和状态信息总被显示在客户端的流媒体状态处理程序     ·KQTSSendMediaFlag:发送 不接收数据     ·KQTSReceiveMediaFlag 接收 不发送数据     在SDP文件说明 参数 以及GWorld 设置下 创建Presentation和Presentation fromFile()     // find audio stream      Stream audioStream = null;  for (int i= ; i<=pres getNumStreams(); i++)   System out println ( stream: + i + : +  pres getIndStream(i));  Stream aStream = pres getIndStream (i);  if (pres hasCharacteristic(aStream   StdQTConstants audioMediaCharacteristic))   audioStream = aStream;  break;      System out println ( audioStream = + audioStream);  pres setVolumes (audioStream );  System out println ( created presentation gworld == +  pres getGWorld() + size == +  mediaParams getWidth() + x +  mediaParams getHeight() + streams == +  pres getNumStreams());    //*******这不是真正地必要的 但它将告诉你怎么通过Presentation游览来挑选各自的流媒体 Presentation getIndStream 会由索引返回一个Stream(附注QuickTime 索引都是基于 ) 它重复这些audioMediaCharacteristic 请求查找音频流 (对于录影 您就要请求visualMediaCharacteristic) 这个实例在audioStream上为左右声道设置音量最大值为     最后 println从Presentation和MediaParams转存一些有意义的元数据      配置Presentation    SettingsDialog sd = new SettingsDialog (pres);  System out println ( Did settings );  pres preroll();  broadcasting = false;    这是设置presentation最后的步骤 SettingsDialog存在用户以输入装置选择的音频和视频 (二个流媒体SDP 文件被指定在Presentation中) 每个流媒体都可由一个压缩格式来定制 (MPEG Sorenson Video H 等) 以及一个分包器(有时由压缩格式定义; 可观察它是否随着压缩格式的改变而自动改变) 这个GUI实例显示在图    >    在此图中 音频默认为计算机连线输入 更改它为iSight 您需要点击Source按钮 提出的可选设备列表显示在图 上    >    最后就是调用Presentation preroll() 如同Movie preroll() 提供Presentation一个机会预先分配资源以及准备好开始流媒体Presentation      提供一个控制GUI    // Make monitor window  startStopButton = new Button ( Start );  configButton = new Button ( Configure );  startStopButton addActionListener (this);  configButton addActionListener (this);  Frame monitorFrame = new Frame ( QTJ Streaming );  monitorFrame setLayout (new BorderLayout());  Panel buttonPanel = new Panel();  buttonPanel add (startStopButton);  buttonPanel add (configButton);  monitorFrame add (buttonPanel BorderLayout SOUTH);  monitorFrame pack();  monitorFrame setVisible(true);    这个为控制和配置Presentation设置了很小的GUI 提供基本的一个起始/停止键和一个配置按钮 按钮作为一个ActionListener提交给this 意味着这个类将需要提供一个actionPerformed方法来处理按钮点击 控制GUI 的屏幕截图显示在图    >    在这点上你也许会问一个有趣的问题: 从什么时候我们开始关心使用GUI提供server? 据推测 这是从Classic Mac OS开始的一个传统 它没有一个用命令行启动和传递参数的程序 但此外 你通常会希望提供一个流媒体数据的预览 并且如果您有一个预览视窗 为什么会也没有一个配置的GUI?    无论如何 这是大概的讨论 因为QTJ 不提供您能使用来预览的一个AWT Component 在有些方面有希望的是 QTFactory将得到一个新的超负荷为采用一个Presentation并且返回一个显示流媒体视频的Component的makeQTComponent 它大概可能使用一些QuickDraw voodoo而完全放弃Java的东西 如果 在各task()中回调(参见下面) 您采取GWorld被及早创建 转换它成Pict 并且作为一份唯一命名的文件 您会看见每一个都是不同的 意味GWorld每次都得到新数据 所以如果您替换掉GWorld 改为能给AWT Component在各通道上定义象素 您会有银幕上的预览 何人有胆量如此做? 在quicktime java list上查看      详细资料    // add shutdown handler to make sure presentation  // gets stopped  Thread presentationStopper = new Thread()   public void run()   try   pres stop();   catch (QTException qte)     ;  Runtime getRuntime() addShutdownHook (presentationStopper);    这个关闭异常分支确定Presentation在程序退出之前被终止 这是重要的原因 象SequenceGrabber Presentation愉快继续运行在您的应用程序退出之后 绑定一个端口 严重的循环 使用您的获取设备保留其它应用程序 等    catch ( QTException e )   e printStackTrace();  System exit ( );        最后 构造函数捕捉并抛出所有的QTExceptions   public void actionPerformed (ActionEvent ae)   System out println ( actionPerformed );  try   if (ae getSource() == startStopButton)   if (broadcasting)   pres stop();  stopTasking();  broadcasting = false;  startStopButton setLabel ( Start );  System out println ( Stopped );   else   pres start();  startTasking();  broadcasting = true;  startStopButton setLabel ( Stop );  System out println ( Started );     else if (ae getSource() == configButton)   new SettingsDialog (pres);     catch (QTException qte)   qte printStackTrace();        这是非常直接的处理起始/终止和设置按钮 如果点击的按钮是起始/终止 设置GUI 就会调用在Presentation上的 start() 或stop() 开始或停止正在执行的任务 (定期回调这个类的task()方法) 为下按钮点击目的设置broadcasting标志 并且更改按钮标签 如果用户点击了配置 它生成为Presentation新的SettingsDialog     public synchronized final void task() throws QTException   pres idle(null);      最后的这个方法实现了继承自Tasking的task()方法并且被在操作开始按钮调用startTasking()后定时的调用 使用简单的调用Presentation idle() 它提供了表达时间来从获取设备取得当前数据 对其编码并传输流出去     运行流媒体客户端    最简单的使客户机看广播的方法是使用QuickTime 播放器打开服务器使用并创建Presentation的同样SDP 文件 这将调用SDP 输入程序连接到流媒体并且开始分析这些内容 注意客户机和服务器不能在同一台机器上 明显地因为服务器为使用表示而占用端口 拒绝客户机对这些端口的使用 图 显示在我的计算机上的流媒体的外观(那是正在播放我的Macross和Escaflowne玩具)    >    如果您使用QuickTime 播放器 您能使用其得到信息指令显示两种流媒体以及他们的格式 在表 您能看有二种媒体: 一条未压缩的 kHz 音频流 和一条H 的视频流    >     结语    对我来说 播放基于Java的QuickTime流媒体比想象的容易多了 最简单的例子 从获取设备播放 只需要少于 个代码行 显然 最困难的部份是了解SDP文件 它被证明是非常的过分讲究并且它的说明文件包含大量应用程序级别程序员不会有的知识 同样不幸的是 QTJ不再提供预览组件 但也许在将来会提供 以及一小段的GWorld/QuickDraw 堆砌也许会在将来制造出这样的组件     本文只包括怎么为实时获取数据设置广播 其它可利用的Sourcers 譬如来自磁盘或任意目录种的那些广播QuickTime 文件 将会在以后的部分中讨论 cha138/Article/program/Java/hx/201311/26490

相关参考

知识大全 安全技术 Java与安全性,第1部分二(图)

安全技术Java与安全性,第1部分二(图)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  用户和

知识大全 安全技术 Java与安全性,第2部分一(图)

安全技术Java与安全性,第2部分一(图)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Pri

知识大全 全面了解Java媒体架构JMF

全面了解Java媒体架构JMF  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Java媒体架构(

知识大全 Java媒体架构基础:Framework Basics

Java媒体架构基础:FrameworkBasics  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

知识大全 java实现彩色图转变为灰度图

  packagework;  importjavaawtGraphicsD;  importjavaawtRenderingHints;  importlorColorSpace;  importj

知识大全 Java抓图程序的实现

Java抓图程序的实现  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  主要难点:  并发线程的控

知识大全 JAVA生成JPG缩略图

JAVA生成JPG缩略图  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在任何一个综合性网站我们

知识大全 java实现缩略图和抓屏幕

  importjavaawtContainer;  importjavaawtDimension;  importjavaawtGraphicsD;  importjavaawtImage;  im

知识大全 Java高级编程:使用打印服务API二(图)

Java高级编程:使用打印服务API二(图)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  选择

知识大全 关于Java单元测试中的伪对象介绍(图)

关于Java单元测试中的伪对象介绍(图)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在单元测