kiwiwings

XSLF - Powerpoint with multiple references to the same video

Apr 6th, 2015
652
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5 9.52 KB | None | 0 0
  1. package org.apache.poi.xslf.usermodel;
  2.  
  3. import java.awt.Rectangle;
  4. import java.awt.image.BufferedImage;
  5. import java.io.ByteArrayOutputStream;
  6. import java.io.FileOutputStream;
  7. import java.io.IOException;
  8. import java.io.InputStream;
  9. import java.io.OutputStream;
  10. import java.net.URL;
  11. import java.text.DecimalFormat;
  12.  
  13. import javax.imageio.ImageIO;
  14. import javax.xml.namespace.QName;
  15.  
  16. import org.apache.poi.openxml4j.opc.PackagePart;
  17. import org.apache.poi.openxml4j.opc.PackagePartName;
  18. import org.apache.poi.openxml4j.opc.PackageRelationship;
  19. import org.apache.poi.openxml4j.opc.PackagingURIHelper;
  20. import org.apache.poi.openxml4j.opc.TargetMode;
  21. import org.apache.poi.sl.usermodel.PictureData.PictureType;
  22. import org.apache.xmlbeans.XmlCursor;
  23. import org.openxmlformats.schemas.drawingml.x2006.main.CTHyperlink;
  24. import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
  25. import org.openxmlformats.schemas.presentationml.x2006.main.CTApplicationNonVisualDrawingProps;
  26. import org.openxmlformats.schemas.presentationml.x2006.main.CTExtension;
  27. import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture;
  28. import org.openxmlformats.schemas.presentationml.x2006.main.CTSlide;
  29. import org.openxmlformats.schemas.presentationml.x2006.main.CTTLCommonMediaNodeData;
  30. import org.openxmlformats.schemas.presentationml.x2006.main.CTTLCommonTimeNodeData;
  31. import org.openxmlformats.schemas.presentationml.x2006.main.CTTimeNodeList;
  32. import org.openxmlformats.schemas.presentationml.x2006.main.STTLTimeIndefinite;
  33. import org.openxmlformats.schemas.presentationml.x2006.main.STTLTimeNodeFillType;
  34. import org.openxmlformats.schemas.presentationml.x2006.main.STTLTimeNodeRestartType;
  35. import org.openxmlformats.schemas.presentationml.x2006.main.STTLTimeNodeType;
  36.  
  37. import com.xuggle.mediatool.IMediaReader;
  38. import com.xuggle.mediatool.MediaListenerAdapter;
  39. import com.xuggle.mediatool.ToolFactory;
  40. import com.xuggle.mediatool.event.IVideoPictureEvent;
  41. import com.xuggle.xuggler.Global;
  42. import com.xuggle.xuggler.IContainer;
  43. import com.xuggle.xuggler.io.InputOutputStreamHandler;
  44.  
  45. public class AddVideoToPptx {
  46.     static DecimalFormat df_time = new DecimalFormat("0.####");
  47.  
  48.     public static void main(String[] args) throws Exception {
  49.         URL video = new URL("http://archive.org/download/test-mpeg/test-mpeg.mpg");
  50.         // URL video = new URL("file:test-mpeg.mpg");
  51.  
  52.         XMLSlideShow pptx = new XMLSlideShow();
  53.  
  54.         // add video file
  55.         String videoFileName = video.getPath().substring(video.getPath().lastIndexOf('/')+1);
  56.         PackagePartName partName = PackagingURIHelper.createPartName("/ppt/media/"+videoFileName);
  57.         PackagePart part = pptx.getPackage().createPart(partName, "video/mpeg");
  58.         OutputStream partOs = part.getOutputStream();
  59.         InputStream fis = video.openStream();
  60.         byte buf[] = new byte[1024];
  61.         for (int readBytes; (readBytes = fis.read(buf)) != -1; partOs.write(buf, 0, readBytes));
  62.         fis.close();
  63.         partOs.close();
  64.  
  65.         XSLFSlide slide1 = pptx.createSlide();
  66.         XSLFPictureShape pv1 = addPreview(pptx, slide1, part, 5, 50, 50);
  67.         addVideo(pptx, slide1, part, pv1, 5);
  68.         addTimingInfo(slide1, pv1);
  69.         XSLFPictureShape pv2 = addPreview(pptx, slide1, part, 9, 50, 250);
  70.         addVideo(pptx, slide1, part, pv2, 9);
  71.         addTimingInfo(slide1, pv2);
  72.  
  73.         FileOutputStream fos = new FileOutputStream("pptx-with-video.pptx");
  74.         pptx.write(fos);
  75.         fos.close();
  76.        
  77.         pptx.close();
  78.     }
  79.  
  80.     static XSLFPictureShape addPreview(XMLSlideShow pptx, XSLFSlide slide1, PackagePart videoPart, double seconds, int x, int y) throws IOException {
  81.         // get preview after 5 sec.
  82.         IContainer ic = IContainer.make();
  83.         InputOutputStreamHandler iosh = new InputOutputStreamHandler(videoPart.getInputStream());
  84.         if (ic.open(iosh, IContainer.Type.READ, null) < 0) return null;
  85.  
  86.         IMediaReader mediaReader = ToolFactory.makeReader(ic);
  87.  
  88.         // stipulate that we want BufferedImages created in BGR 24bit color space
  89.         mediaReader.setBufferedImageTypeToGenerate(BufferedImage.TYPE_3BYTE_BGR);
  90.  
  91.         ImageSnapListener isl = new ImageSnapListener(seconds);
  92.         mediaReader.addListener(isl);
  93.  
  94.         // read out the contents of the media file and
  95.         // dispatch events to the attached listener
  96.         while (!isl.hasFired && mediaReader.readPacket() == null) ;
  97.  
  98.         mediaReader.close();
  99.         ic.close();
  100.  
  101.         // add snapshot
  102.         BufferedImage image1 = isl.image;
  103.         ByteArrayOutputStream bos = new ByteArrayOutputStream();
  104.         ImageIO.write(image1, "jpeg", bos);
  105.         XSLFPictureData snap = pptx.addPicture(bos.toByteArray(), PictureType.JPEG);
  106.         XSLFPictureShape pic1 = slide1.createPicture(snap);
  107.         pic1.setAnchor(new Rectangle(x, y, image1.getWidth(), image1.getHeight()));
  108.         return pic1;
  109.     }
  110.  
  111.     static void addVideo(XMLSlideShow pptx, XSLFSlide slide1, PackagePart videoPart, XSLFPictureShape pic1, double seconds) throws IOException {
  112.  
  113.         // add video shape
  114.         PackagePartName partName = videoPart.getPartName();
  115.         PackageRelationship prsEmbed1 = slide1.getPackagePart().addRelationship(partName, TargetMode.INTERNAL, "http://schemas.microsoft.com/office/2007/relationships/media");
  116.         PackageRelationship prsExec1 = slide1.getPackagePart().addRelationship(partName, TargetMode.INTERNAL, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/video");
  117.         CTPicture xpic1 = (CTPicture)pic1.getXmlObject();
  118.         CTHyperlink link1 = xpic1.getNvPicPr().getCNvPr().addNewHlinkClick();
  119.         link1.setId("");
  120.         link1.setAction("ppaction://media");
  121.  
  122.         // add video relation
  123.         CTApplicationNonVisualDrawingProps nvPr = xpic1.getNvPicPr().getNvPr();
  124.         nvPr.addNewVideoFile().setLink(prsExec1.getId());
  125.         CTExtension ext = nvPr.addNewExtLst().addNewExt();
  126.         // see http://msdn.microsoft.com/en-us/library/dd950140(v=office.12).aspx
  127.         ext.setUri("{DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230}");
  128.         String p14Ns = "http://schemas.microsoft.com/office/powerpoint/2010/main";
  129.         XmlCursor cur = ext.newCursor();
  130.         cur.toEndToken();
  131.         cur.beginElement(new QName(p14Ns, "media", "p14"));
  132.         cur.insertNamespace("p14", p14Ns);
  133.         cur.insertAttributeWithValue(new QName(STRelationshipId.type.getName().getNamespaceURI(), "embed"), prsEmbed1.getId());
  134.         cur.beginElement(new QName(p14Ns, "trim", "p14"));
  135.         cur.insertAttributeWithValue("st", df_time.format(seconds*1000.0));
  136.         cur.dispose();
  137.  
  138.     }
  139.  
  140.     static void addTimingInfo(XSLFSlide slide1, XSLFPictureShape pic1) {
  141.         // add slide timing information, so video can be controlled
  142.         CTSlide xslide = slide1.getXmlObject();
  143.         CTTimeNodeList ctnl;
  144.         if (!xslide.isSetTiming()) {
  145.             CTTLCommonTimeNodeData ctn = xslide.addNewTiming().addNewTnLst().addNewPar().addNewCTn();
  146.             ctn.setDur(STTLTimeIndefinite.INDEFINITE);
  147.             ctn.setRestart(STTLTimeNodeRestartType.NEVER);
  148.             ctn.setNodeType(STTLTimeNodeType.TM_ROOT);
  149.             ctnl = ctn.addNewChildTnLst();
  150.         } else {
  151.             ctnl = xslide.getTiming().getTnLst().getParArray(0).getCTn().getChildTnLst();
  152.         }
  153.  
  154.         CTTLCommonMediaNodeData cmedia = ctnl.addNewVideo().addNewCMediaNode();
  155.         cmedia.setVol(80000);
  156.         CTTLCommonTimeNodeData ctn = cmedia.addNewCTn();
  157.         ctn.setFill(STTLTimeNodeFillType.HOLD);
  158.         ctn.setDisplay(false);
  159.         ctn.addNewStCondLst().addNewCond().setDelay(STTLTimeIndefinite.INDEFINITE);
  160.         cmedia.addNewTgtEl().addNewSpTgt().setSpid(""+pic1.getShapeId());
  161.     }
  162.  
  163.  
  164.     static class ImageSnapListener extends MediaListenerAdapter {
  165.         final double SECONDS_BETWEEN_FRAMES;
  166.         final long MICRO_SECONDS_BETWEEN_FRAMES;
  167.         boolean hasFired = false;
  168.         BufferedImage image = null;
  169.  
  170.         // The video stream index, used to ensure we display frames from one and
  171.         // only one video stream from the media container.
  172.         int mVideoStreamIndex = -1;
  173.  
  174.         // Time of last frame write
  175.         long mLastPtsWrite = Global.NO_PTS;
  176.  
  177.         public ImageSnapListener(double seconds) {
  178.             SECONDS_BETWEEN_FRAMES = seconds;
  179.             MICRO_SECONDS_BETWEEN_FRAMES =
  180.                     (long)(Global.DEFAULT_PTS_PER_SECOND * SECONDS_BETWEEN_FRAMES);
  181.         }
  182.  
  183.  
  184.         @Override
  185.         public void onVideoPicture(IVideoPictureEvent event) {
  186.  
  187.             if (event.getStreamIndex() != mVideoStreamIndex) {
  188.                 // if the selected video stream id is not yet set, go ahead an
  189.                 // select this lucky video stream
  190.                 if (mVideoStreamIndex != -1) return;
  191.                 mVideoStreamIndex = event.getStreamIndex();
  192.             }
  193.  
  194.             long evtTS = event.getTimeStamp();
  195.  
  196.             // if uninitialized, back date mLastPtsWrite to get the very first frame
  197.             if (mLastPtsWrite == Global.NO_PTS)
  198.                 mLastPtsWrite = Math.max(0, evtTS - MICRO_SECONDS_BETWEEN_FRAMES);
  199.  
  200.             // if it's time to write the next frame
  201.             if (evtTS - mLastPtsWrite >= MICRO_SECONDS_BETWEEN_FRAMES) {
  202.                 if (!hasFired) {
  203.                     image = event.getImage();
  204.                     hasFired = true;
  205.                 }
  206.                 // update last write time
  207.                 mLastPtsWrite += MICRO_SECONDS_BETWEEN_FRAMES;
  208.             }
  209.         }
  210.     }
  211.  
  212. }
Advertisement
Add Comment
Please, Sign In to add comment