video.html 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]--><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="Asciidoctor 1.5.4"><title>Video</title><link rel="stylesheet" href="./asciidoctor.css">
  2. <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css">
  3. <link rel="stylesheet" href="./coderay-asciidoctor.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/2/docsearch.min.css"><link rel="stylesheet" href="/home/travis/build/jMonkeyEngine/wiki/build/asciidoc/html5/jme3/advanced/twemoji-awesome.css"></head><body class="article toc2 toc-left"><div id="header"><div id="toolbar"><a href="https://github.com/jMonkeyEngine/wiki/edit/master/src/docs/asciidoc/jme3/advanced/video.adoc"><i class="fa fa-pencil-square" aria-hidden="true"></i></a><a href="https://github.com/jMonkeyEngine/wiki/new/master/src/docs/asciidoc/jme3/advanced/"><i class="fa fa-plus-square" aria-hidden="true"></i></a><input dir="auto" style="position: relative; vertical-align: top;" spellcheck="false" autocomplete="off" class="searchbox__input aa-input" id="doc-search" name="search" placeholder="Search in the doc" required="required" type="search"></div><h1>Video</h1><div class="details"><span class="author" id="author"></span><br><span id="revnumber">version ,</span> <span id="revdate">2016/03/17 20:48</span></div><div id="toc" class="toc2"><div id="toctitle">Table of Contents</div></div></div><div id="content"><div class="paragraph"><p>Relevant forum topics:</p></div>
  4. <div class="paragraph"><p><a href="http://hub.jmonkeyengine.org/t/ive-made-a-movieappstate-so-you-dont-have-to/31673">http://hub.jmonkeyengine.org/t/ive-made-a-movieappstate-so-you-dont-have-to/31673</a></p></div>
  5. <div class="paragraph"><p><a href="http://hub.jmonkeyengine.org/t/news-about-playing-videos-on-jme/30084/5">http://hub.jmonkeyengine.org/t/news-about-playing-videos-on-jme/30084/5</a></p></div>
  6. <div class="paragraph"><p><a href="http://www.java-gaming.org/topics/java-media-player/27100/view.html">YUNPM - a Java Media Player</a> (java-gaming.org)</p></div>
  7. <div class="paragraph"><p><a href="http://www.java-gaming.org/topics/gstlwjgl-yet-another-media-player/27146/view.html">GstLWJGL</a> (java-gaming.org)</p></div>
  8. <div class="paragraph"><p><a href="http://jogamp.org/deployment/jogamp-next/javadoc/jogl/javadoc/com/jogamp/opengl/util/av/package-summary.html">GL Media Player</a> (jogamp.org)</p></div>
  9. <div class="paragraph"><p><a href="http://www.xuggle.com/xuggler">Xuggler</a></p></div>
  10. <div class="admonitionblock warning"><table><tr><td class="icon"><i class="fa icon-warning" title="Warning"></i></td><td class="content"><div class="paragraph"><p>This <abbr title="Application Programming Interface">API</abbr> is deprecated.</p></div></td></tr></table></div>
  11. <div class="paragraph"><p>jMonkeyEngine supports Jheora Ogg video (<code>com.jme3.video</code>).</p></div>
  12. <div class="paragraph"><p>Full code sample here: <a href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/jheora/com/jme3/video/TestVideoPlayer.java">TestVideoPlayer.java</a></p></div>
  13. <div class="paragraph"><p>You create either a file inputstream to load the video from your hard drive:</p></div>
  14. <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">FileInputStream</span> fis = <span class="keyword">new</span> <span class="predefined-type">FileInputStream</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">E:</span><span class="char">\\</span><span class="content">my_bunny.ogg</span><span class="delimiter">&quot;</span></span>);</code></pre></div></div>
  15. <div class="paragraph"><p>Or you stream the video live from a web location:</p></div>
  16. <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">InputStream</span> fis = <span class="keyword">new</span> <span class="predefined-type">URL</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">http://server/my_video.ogg</span><span class="delimiter">&quot;</span></span>).openStream();</code></pre></div></div>
  17. <div class="paragraph"><p>Setting the queued frames to a value value higher than 5 (<code>videoQueue = new VQueue(5);</code>) will make web streamed playback smoother at the cost of memory.
  18. Here is an example of video streaming in context:</p></div>
  19. <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"> <span class="directive">private</span> <span class="type">void</span> createVideo(){
  20. <span class="keyword">try</span> {
  21. <span class="predefined-type">InputStream</span> fis = <span class="keyword">new</span> <span class="predefined-type">URL</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">http://mirrorblender.top-ix.org/peach/</span><span class="delimiter">&quot;</span></span>+
  22. <span class="string"><span class="delimiter">&quot;</span><span class="content">bigbuckbunny_movies/big_buck_bunny_480p_stereo.ogg</span><span class="delimiter">&quot;</span></span>).openStream();
  23. videoQueue = <span class="keyword">new</span> VQueue(<span class="integer">5</span>); <span class="comment">// streaming quality vs memory</span>
  24. decoder = <span class="keyword">new</span> AVThread(fis, videoQueue);
  25. videoThread = <span class="keyword">new</span> <span class="predefined-type">Thread</span>(decoder, <span class="string"><span class="delimiter">&quot;</span><span class="content">Jheora Video Decoder</span><span class="delimiter">&quot;</span></span>);
  26. videoThread.setDaemon(<span class="predefined-constant">true</span>);
  27. videoThread.start();
  28. masterClock = decoder.getMasterClock();
  29. } <span class="keyword">catch</span> (<span class="exception">IOException</span> ex) {
  30. ex.printStackTrace();
  31. }
  32. }</code></pre></div></div>
  33. <div class="paragraph"><p>Use the simpleUpdate() method to play the audio:</p></div>
  34. <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"> <span class="annotation">@Override</span>
  35. <span class="directive">public</span> <span class="type">void</span> simpleUpdate(<span class="type">float</span> tpf){
  36. <span class="keyword">if</span> (source == <span class="predefined-constant">null</span>){
  37. <span class="keyword">if</span> (decoder.getAudioStream() != <span class="predefined-constant">null</span>){
  38. source = <span class="keyword">new</span> AudioNode(decoder.getAudioStream(), <span class="predefined-constant">null</span>);
  39. source.setPositional(<span class="predefined-constant">false</span>);
  40. source.setReverbEnabled(<span class="predefined-constant">false</span>);
  41. audioRenderer.playSource(source);
  42. }<span class="keyword">else</span>{
  43. <span class="comment">// uncomment this statement to be able to play videos</span>
  44. <span class="comment">// without audio.</span>
  45. <span class="keyword">return</span>;
  46. }
  47. }
  48. <span class="keyword">if</span> (waitTime &gt; <span class="integer">0</span>){
  49. waitTime -= tpf;
  50. <span class="keyword">if</span> (waitTime &gt; <span class="integer">0</span>)
  51. <span class="keyword">return</span>;
  52. <span class="keyword">else</span>{
  53. waitTime = <span class="integer">0</span>;
  54. drawFrame(frameToDraw);
  55. frameToDraw = <span class="predefined-constant">null</span>;
  56. }
  57. }<span class="keyword">else</span>{
  58. VFrame frame;
  59. <span class="keyword">try</span> {
  60. frame = videoQueue.take();
  61. } <span class="keyword">catch</span> (<span class="exception">InterruptedException</span> ex){
  62. stop();
  63. <span class="keyword">return</span>;
  64. }
  65. <span class="keyword">if</span> (frame.getTime() &lt; lastFrameTime){
  66. videoQueue.returnFrame(frame);
  67. <span class="keyword">return</span>;
  68. }
  69. <span class="keyword">if</span> (frame.getTime() == -<span class="integer">2</span>){
  70. <span class="comment">// end of stream</span>
  71. <span class="predefined-type">System</span>.out.println(<span class="string"><span class="delimiter">&quot;</span><span class="content">End of stream</span><span class="delimiter">&quot;</span></span>);
  72. stop();
  73. <span class="keyword">return</span>;
  74. }
  75. <span class="type">long</span> AV_SYNC_THRESHOLD = <span class="integer">1</span> * Clock.MILLIS_TO_NANOS;
  76. <span class="type">long</span> delay = frame.getTime() - lastFrameTime;
  77. <span class="type">long</span> diff = frame.getTime() - masterClock.getTime();
  78. <span class="type">long</span> syncThresh = delay &gt; AV_SYNC_THRESHOLD ? delay : AV_SYNC_THRESHOLD;
  79. <span class="comment">// if difference is more than 1 second, synchronize.</span>
  80. <span class="keyword">if</span> (<span class="predefined-type">Math</span>.abs(diff) &lt; Clock.SECONDS_TO_NANOS){
  81. <span class="keyword">if</span>(diff &lt;= -syncThresh) {
  82. delay = <span class="integer">0</span>;
  83. } <span class="keyword">else</span> <span class="keyword">if</span>(diff &gt;= syncThresh) {
  84. delay = <span class="integer">2</span> * delay;
  85. }
  86. }
  87. <span class="predefined-type">System</span>.out.println(<span class="string"><span class="delimiter">&quot;</span><span class="content">M: </span><span class="delimiter">&quot;</span></span>+decoder.getSystemClock().getTimeSeconds()+
  88. <span class="string"><span class="delimiter">&quot;</span><span class="content">, V: </span><span class="delimiter">&quot;</span></span>+decoder.getVideoClock().getTimeSeconds()+
  89. <span class="string"><span class="delimiter">&quot;</span><span class="content">, A: </span><span class="delimiter">&quot;</span></span>+decoder.getAudioClock().getTimeSeconds());
  90. <span class="keyword">if</span> (delay &gt; <span class="integer">0</span>){
  91. waitNanos(delay);
  92. drawFrame(frame);
  93. }<span class="keyword">else</span>{
  94. videoQueue.returnFrame(frame);
  95. lastFrameTime = frame.getTime();
  96. }
  97. }
  98. }</code></pre></div></div>
  99. <div class="paragraph"><p>Helper Methods:</p></div>
  100. <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"> <span class="directive">private</span> <span class="type">void</span> drawFrame(VFrame frame){
  101. <span class="predefined-type">Image</span> image = frame.getImage();
  102. frame.setImage(image);
  103. picture.setTexture(assetManager, frame, <span class="predefined-constant">false</span>);
  104. <span class="comment">// note: this forces renderer to upload frame immediately,</span>
  105. <span class="comment">// since it is going to be returned to the video queue pool</span>
  106. <span class="comment">// it could be used again.</span>
  107. renderer.setTexture(<span class="integer">0</span>, frame);
  108. videoQueue.returnFrame(frame);
  109. lastFrameTime = frame.getTime();
  110. }</code></pre></div></div>
  111. <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"> <span class="directive">private</span> <span class="type">void</span> waitNanos(<span class="type">long</span> time){
  112. <span class="type">long</span> millis = (<span class="type">long</span>) (time / Clock.MILLIS_TO_NANOS);
  113. <span class="type">int</span> nanos = (<span class="type">int</span>) (time - (millis * Clock.MILLIS_TO_NANOS));
  114. <span class="keyword">try</span> {
  115. <span class="predefined-type">Thread</span>.sleep(millis, nanos);
  116. }<span class="keyword">catch</span> (<span class="exception">InterruptedException</span> ex){
  117. stop();
  118. <span class="keyword">return</span>;
  119. }
  120. }</code></pre></div></div></div><div id="footer"><div id="footer-text">Version <br>Last updated 2019-12-20 23:30:51 +00:00</div></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/2/docsearch.min.js"></script><script>docsearch({
  121. apiKey: 'a736b6d93de805e26ec2f49b55013fbd',
  122. indexName: 'jmonkeyengine',
  123. inputSelector: '#doc-search',
  124. debug: false // Set debug to true if you want to inspect the dropdown
  125. });</script></body></html>