001 package railo.runtime.tag; 002 003 004 import java.io.IOException; 005 import java.io.InputStream; 006 import java.io.OutputStream; 007 import java.util.Iterator; 008 import java.util.Random; 009 010 import railo.commons.io.res.Resource; 011 import railo.commons.io.res.util.ResourceUtil; 012 import railo.commons.lang.ClassException; 013 import railo.commons.lang.StringUtil; 014 import railo.loader.util.Util; 015 import railo.runtime.PageContext; 016 import railo.runtime.exp.ApplicationException; 017 import railo.runtime.exp.PageException; 018 import railo.runtime.ext.tag.TagSupport; 019 import railo.runtime.op.Caster; 020 import railo.runtime.type.Collection.Key; 021 import railo.runtime.type.KeyImpl; 022 import railo.runtime.type.Struct; 023 import railo.runtime.type.StructImpl; 024 import railo.runtime.type.util.KeyConstants; 025 import railo.runtime.video.ProfileCollection; 026 import railo.runtime.video.VideoExecuter; 027 import railo.runtime.video.VideoInfo; 028 import railo.runtime.video.VideoInput; 029 import railo.runtime.video.VideoInputImpl; 030 import railo.runtime.video.VideoOutput; 031 import railo.runtime.video.VideoOutputImpl; 032 import railo.runtime.video.VideoProfile; 033 import railo.runtime.video.VideoProfileImpl; 034 import railo.runtime.video.VideoUtilImpl; 035 036 /** 037 * implementation of the tag Compiler 038 */ 039 public class Video extends TagSupport { 040 041 private static final int ACTION_CONVERT=0; 042 private static final int ACTION_INFO=1; 043 private static final int ACTION_CONCAT=2; 044 private static final int ACTION_CUT_IMAGE=4; 045 private static final int ACTION_INSTALL=8; 046 private static final int ACTION_UNINSTALL=16; 047 048 public static final int NAMECONFLICT_UNDEFINED=0; 049 public static final int NAMECONFLICT_ERROR=1; 050 public static final int NAMECONFLICT_SKIP=2; 051 public static final int NAMECONFLICT_OVERWRITE=3; 052 public static final int NAMECONFLICT_MAKEUNIQUE=4; 053 054 public static final int EXECUTION_QUALITY=0; 055 public static final int EXECUTION_PERFORMANCE=1; 056 private static final Key SOURCE = KeyConstants._source; 057 private static final Key SOURCE1 = KeyImpl.intern("source1"); 058 private static final Key SOURCE2 = KeyImpl.intern("source2"); 059 private static final Key AUDIO = KeyImpl.intern("audio"); 060 private static final Key VIDEO = KeyImpl.intern("video"); 061 062 private static VideoUtilImpl util=VideoUtilImpl.getInstance(); 063 064 065 private String result="cfvideo"; 066 private int action; 067 private String strAction; 068 private VideoInput source; 069 private VideoInput source1; 070 private VideoInput source2; 071 private VideoOutput destination; 072 private int nameconflict=NAMECONFLICT_UNDEFINED; 073 private String name; 074 private int width=-1; 075 private int height=-1; 076 private String strWidth; 077 private String strHeight; 078 private Struct data; 079 080 081 private long audiosamplerate=0; 082 private long audioBitrate=0; 083 private double startTime=0; 084 private long startFrame=0; 085 private double maxTime=0; 086 private long maxFrame=0; 087 088 private VideoProfile profile=null; 089 090 private int aspectRatio; 091 private int framerate; 092 private long videoBitrate; 093 private long videoBitrateMin; 094 private long videoBitrateMax; 095 private long videoBitrateTolerance; 096 private String debug=null; 097 098 private String author; 099 private String title; 100 private String comment; 101 private String copyright; 102 private String videoCodec; 103 private String audioCodec; 104 private long buffersize; 105 private int execution=EXECUTION_PERFORMANCE; 106 private static ProfileCollection _profileCollection; 107 108 public Video(){ 109 110 } 111 112 @Override 113 public void release() { 114 super.release(); 115 result="cfvideo"; 116 execution=EXECUTION_PERFORMANCE; 117 source=null; 118 source1=null; 119 source2=null; 120 destination=null; 121 nameconflict=NAMECONFLICT_UNDEFINED; 122 name=null; 123 width=-1; 124 height=-1; 125 profile=null; 126 audioBitrate=0; 127 videoCodec=null; 128 audioCodec=null; 129 130 audiosamplerate=0; 131 aspectRatio=0; 132 framerate=0; 133 videoBitrate=0; 134 videoBitrateMin=0; 135 videoBitrateMax=0; 136 videoBitrateTolerance=0; 137 buffersize=0; 138 author=null; 139 title=null; 140 comment=null; 141 copyright=null; 142 debug=null; 143 144 maxTime=0; 145 maxFrame=0; 146 startTime=0; 147 startFrame=0; 148 strWidth=null; 149 strHeight=null; 150 data=null; 151 } 152 153 154 155 /** 156 * @param action the action to set 157 * @throws PageException 158 */ 159 public void setAction(String action) throws PageException { 160 strAction=action; 161 action=action.toLowerCase().trim(); 162 if(action.equals("concat")) this.action=ACTION_CONCAT; 163 else if(action.equals("merge")) this.action=ACTION_CONCAT; 164 else if(action.equals("convert")) this.action=ACTION_CONVERT; 165 //else if(action.equals("cut")) this.action=ACTION_CUT; 166 else if(action.equals("cut image")) this.action=ACTION_CUT_IMAGE; 167 else if(action.equals("cutimage")) this.action=ACTION_CUT_IMAGE; 168 else if(action.equals("cut_image")) this.action=ACTION_CUT_IMAGE; 169 else if(action.equals("cut-image")) this.action=ACTION_CUT_IMAGE; 170 else if(action.equals("info")) this.action=ACTION_INFO; 171 172 else if(action.equals("install")) this.action=ACTION_INSTALL; 173 else if(action.equals("uninstall")) this.action=ACTION_UNINSTALL; 174 175 else throw doThrow("invalid value for attribute action for tag video ["+action+"], " + 176 "valid actions are [concat, convert, cutImage, info]"); 177 178 } 179 180 /** 181 * @param source the source to set 182 * @throws PageException 183 */ 184 public void setSource(String source) throws PageException { 185 this.source = new VideoInputImpl(ResourceUtil.toResourceExisting(pageContext, source)); 186 } 187 188 public void setData(Struct data){ 189 this.data=data; 190 } 191 192 /** 193 * @param destination the destination to set 194 * @throws PageException 195 */ 196 public void setDestination(String destination) { 197 this.destination = new VideoOutputImpl(ResourceUtil.toResourceNotExisting(pageContext, destination)); 198 } 199 200 /** set the value nameconflict 201 * Action to take if filename is the same as that of a file in the directory. 202 * @param nameconflict value to set 203 * @throws ApplicationException 204 **/ 205 public void setNameconflict(String nameconflict) throws PageException { 206 nameconflict=nameconflict.toLowerCase().trim(); 207 if("error".equals(nameconflict)) this.nameconflict=NAMECONFLICT_ERROR; 208 else if("skip".equals(nameconflict)) this.nameconflict=NAMECONFLICT_SKIP; 209 else if("overwrite".equals(nameconflict)) this.nameconflict=NAMECONFLICT_OVERWRITE; 210 else if("makeunique".equals(nameconflict)) this.nameconflict=NAMECONFLICT_MAKEUNIQUE; 211 else throw doThrow("invalid value for attribute nameconflict ["+nameconflict+"]", 212 "valid values are [error,skip,overwrite,makeunique]"); 213 } 214 215 public void setProfile(String strProfile) throws PageException { 216 VideoProfile p = getProfile(strProfile); 217 if(p!=null)profile=p.duplicate(); 218 else throw doThrow("invalid profile defintion ["+strProfile+"], valid profiles are ["+getProfileKeyList()+"]"); 219 } 220 221 public void setExecution(String execution) throws PageException { 222 223 execution=execution.toLowerCase().trim(); 224 if("quality".equals(execution)) this.execution=EXECUTION_QUALITY; 225 else if("q".equals(execution)) this.execution=EXECUTION_QUALITY; 226 else if("performance".equals(execution)) this.execution=EXECUTION_PERFORMANCE; 227 else if("p".equals(execution)) this.execution=EXECUTION_PERFORMANCE; 228 else throw doThrow("invalid value for attribute execution ["+execution+"]", 229 "valid values are [quality,performance]"); 230 } 231 232 public void setQuality(String strQuality) throws PageException { 233 setProfile(strQuality); 234 } 235 236 @Override 237 public int doStartTag() throws PageException { 238 239 try { 240 if(action==ACTION_CONVERT) doActionConvert(); 241 else if(action==ACTION_CONCAT) doActionConcat(); 242 else if(action==ACTION_CUT_IMAGE) doActionCutImage(); 243 else if(action==ACTION_INFO) doActionInfo(); 244 else if(action==ACTION_INSTALL) doActionInstall(); 245 else if(action==ACTION_UNINSTALL) doActionUninstall(); 246 } 247 catch(Throwable t) { 248 throw Caster.toPageException(t); 249 } 250 return SKIP_BODY; 251 } 252 253 254 255 private void doActionInstall() throws ClassException, IOException { 256 if(data==null)data=new StructImpl(); 257 getVideoExecuter().install(pageContext.getConfig(),data); 258 } 259 private void doActionUninstall() throws ClassException, IOException { 260 getVideoExecuter().uninstall(pageContext.getConfig()); 261 } 262 263 public Struct doActionInfo() throws PageException, IOException { 264 return doActionInfo(source); 265 266 } 267 268 private Struct doActionInfo(VideoInput source) throws PageException, IOException { 269 270 // precheck settings 271 checkFile(source,"source", true, true, false); 272 273 //VideoConfig vc = getConfig(); 274 debug(source); 275 Struct info = toStruct(getVideoExecuter().info(pageContext.getConfig(), source)); 276 pageContext.setVariable(result,info); 277 return info; 278 279 } 280 281 private VideoExecuter getVideoExecuter() throws ClassException { 282 return VideoUtilImpl.createVideoExecuter(pageContext.getConfig()); 283 } 284 285 286 287 private VideoInfo getInfo(VideoInput source) throws PageException, IOException { 288 289 // precheck settings 290 checkFile(source,"source", true, true, false); 291 292 // execute 293 return getVideoExecuter().info(pageContext.getConfig(),source); 294 //print.out(raw); 295 296 // write cfvideo 297 //return new Info(raw,true,startTime,maxTime); 298 } 299 300 301 private void doActionCutImage() throws PageException, IOException { 302 303 // precheck settings 304 checkFile(source,"source", true, true, false); 305 if(!checkDestination(source,destination,name,nameconflict)) return; 306 307 // input 308 if(profile==null)profile=new VideoProfileImpl(); 309 310 // settings 311 settings(destination,profile); 312 313 destination.setMaxFrames(1); 314 destination.setFormat("image2"); 315 // execute 316 Struct info=toStruct(getVideoExecuter().convert(pageContext.getConfig(),new VideoInput[]{source},destination,profile)); 317 318 // write cfvideo 319 debug(source); 320 pageContext.setVariable(result,info); 321 322 //setResult(raw,false); 323 324 } 325 326 327 328 private void doActionConcat() throws PageException, IOException { 329 // precheck settings 330 checkFile(source1,"source1", true, true, false); 331 checkFile(source2,"source2", true, true, false); 332 if(!checkDestination(source1,destination,name,nameconflict)) return; 333 334 Pair s1 =toMpeg(source1); 335 Pair s2 =toMpeg(source2); 336 source = new VideoInputImpl(pageContext.getConfig().getTempDirectory().getRealResource("tmp-"+new Random().nextInt()+".mpg")); 337 try { 338 merge(s1.res,s2.res,source.getResource()); 339 Struct sct = doActionConvert(); 340 sct.setEL(SOURCE1, s1.sct); 341 sct.setEL(SOURCE2, s2.sct); 342 sct.removeEL(SOURCE); 343 344 } 345 finally { 346 source.getResource().delete(); 347 if(!s1.res.equals(source1.getResource()))s1.res.delete(); 348 if(!s2.res.equals(source2.getResource()))s2.res.delete(); 349 } 350 351 } 352 353 354 355 private void merge(Resource in1, Resource in2, Resource out) throws IOException { 356 InputStream is1=null; 357 InputStream is2=null; 358 OutputStream os=null; 359 try { 360 is1=in1.getInputStream(); 361 is2=in2.getInputStream(); 362 os=out.getOutputStream(); 363 } 364 catch(IOException ioe) { 365 Util.closeEL(is1); 366 Util.closeEL(is2); 367 Util.closeEL(os); 368 throw ioe; 369 } 370 371 try { 372 copy(is1, os); 373 copy(is2, os); 374 } 375 finally { 376 Util.closeEL(is1); 377 Util.closeEL(is2); 378 Util.closeEL(os); 379 } 380 } 381 382 383 public final static void copy(InputStream in, OutputStream out) throws IOException { 384 byte[] buffer = new byte[0xffff]; 385 int len; 386 while((len = in.read(buffer)) !=-1) 387 out.write(buffer, 0, len); 388 } 389 390 391 392 393 private Pair toMpeg(VideoInput vi) throws PageException, IOException { 394 VideoInfo info = getInfo(vi); 395 //Struct sct = _doActionInfo(vi); 396 397 398 if("mpeg1video".equals(info.getVideoCodec())) 399 return new Pair(vi.getResource(),toStruct(info)); 400 401 VideoOutput tmp = new VideoOutputImpl(pageContext.getConfig().getTempDirectory().getRealResource("tmp-"+new Random().nextInt()+".mpg")); 402 try { 403 doActionConvert(vi,tmp,null,null,NAMECONFLICT_ERROR); 404 return new Pair(tmp.getResource(),toStruct(info)); 405 } 406 catch(PageException pe) { 407 tmp.getResource().delete(); 408 throw pe; 409 } 410 catch(IOException ioe) { 411 tmp.getResource().delete(); 412 throw ioe; 413 } 414 415 } 416 417 418 419 private Struct doActionConvert() throws PageException, IOException { 420 return doActionConvert(source,destination,profile,name,nameconflict); 421 } 422 private Struct doActionConvert(VideoInput source,VideoOutput destination, VideoProfile quality,String name, int nameconflict) throws PageException, IOException { 423 424 // precheck settings 425 checkFile(source,"source", true, true, false); 426 if(!checkDestination(source,destination,name,nameconflict)) return new StructImpl(); 427 428 // input 429 if(quality==null)quality=new VideoProfileImpl(); 430 431 // settings 432 settings(destination,quality); 433 434 // execute 435 Struct info = toStruct(getVideoExecuter().convert(pageContext.getConfig(),new VideoInput[]{source},destination,quality)); 436 437 // write cfvideo 438 debug(source); 439 440 pageContext.setVariable(result,info); 441 return info; 442 //return setResult(raw,false); 443 } 444 445 446 private void debug(VideoInput vi) throws PageException { 447 if(!StringUtil.isEmpty(debug))pageContext.setVariable(debug, vi.getCommandAsString()); 448 } 449 450 private void settings(VideoOutput vo,VideoProfile vq) throws PageException, IOException { 451 defineSize(vq,new VideoInput[]{source}); 452 if(audioBitrate>0)vq.setAudioBitrate(audioBitrate); 453 if(aspectRatio>0)vq.setAspectRatio(aspectRatio); 454 if(framerate>0)vq.setFramerate(framerate); 455 if(videoBitrate>0)vq.setVideoBitrate(videoBitrate); 456 if(videoBitrateMin>0)vq.setVideoBitrateMin(videoBitrateMin); 457 if(videoBitrateMax>0)vq.setVideoBitrateMax(videoBitrateMax); 458 if(videoBitrateTolerance>0)vq.setVideoBitrateTolerance(videoBitrateTolerance); 459 if(audiosamplerate>0)vq.setAudioSamplerate(audiosamplerate); 460 if(buffersize>0)vq.setBufferSize(buffersize); 461 if(execution==EXECUTION_QUALITY)vq.setPass(2); 462 463 if(!StringUtil.isEmpty(title))vo.setTitle(title); 464 if(!StringUtil.isEmpty(author))vo.setAuthor(author); 465 if(!StringUtil.isEmpty(comment))vo.setComment(comment); 466 if(!StringUtil.isEmpty(copyright))vo.setCopyright(copyright); 467 if(!StringUtil.isEmpty(videoCodec))vq.setVideoCodec(videoCodec); 468 if(!StringUtil.isEmpty(audioCodec))vq.setAudioCodec(audioCodec); 469 470 471 472 if(framerate==0 && (startFrame>0 || maxTime>0)) { 473 framerate=(int)getInfo(source).getFramerate(); 474 } 475 476 // start 477 if(startFrame>0) { 478 if(framerate>0) startTime=(startFrame/framerate); 479 } 480 if(startTime>0)destination.setOffset(startTime); 481 482 // max 483 if(maxTime>0) { 484 if(framerate>0) maxFrame=(long)(maxTime*framerate); 485 } 486 if(maxTime>0)vo.setMaxFrames(maxFrame); 487 488 // maxtime (only for cfvideo struct) 489 if(maxFrame>0 && maxTime==0) { 490 if(framerate!=-1) maxTime=maxFrame/framerate; 491 } 492 destination.setFrameRate(framerate); 493 494 } 495 496 private ProfileCollection getProfileCollection() throws PageException { 497 return getProfileCollection(pageContext); 498 } 499 500 public static ProfileCollection getProfileCollection(PageContext pc) throws PageException { 501 if(_profileCollection==null) { 502 try { 503 _profileCollection=new ProfileCollection(pc.getConfig()); 504 } 505 catch (Exception e) { 506 throw Caster.toPageException(e); 507 } 508 } 509 return _profileCollection; 510 } 511 512 private void defineSize(VideoProfile quality, VideoInput[] sources) throws PageException { 513 if(strWidth!=null || strHeight!=null) { 514 int[] dim = VideoUtilImpl.getInstance().calculateDimension(pageContext, sources, width, strWidth, height, strHeight); 515 quality.setDimension(dim[0], dim[1]); 516 } 517 } 518 519 private void checkFile(VideoInput vi, String label, boolean exist, boolean canRead, boolean canWrite) throws PageException { 520 if(vi==null) { 521 throw doThrow("attribute "+label+" is required for tag video action "+strAction); 522 } 523 checkFile(vi.getResource(), label, exist, canRead, canWrite); 524 } 525 526 private void checkFile(VideoOutput vo, String label, boolean exist, boolean canRead, boolean canWrite) throws PageException { 527 if(vo==null) { 528 throw doThrow("attribute "+label+" is required for tag video action "+strAction); 529 } 530 checkFile(vo.getResource(), label, exist, canRead, canWrite); 531 } 532 533 534 private void checkFile(Resource res, String label, boolean exist, boolean canRead, boolean canWrite) throws PageException { 535 536 if(res==null) { 537 throw doThrow("attribute "+label+" is required for tag video action "+strAction); 538 } 539 540 541 if(!res.exists()) { 542 if(exist)throw doThrow(""+label+" file does not exist"); 543 } 544 else { 545 if(!res.isFile()) 546 throw doThrow(label+" ["+res.toString()+"] is not a file"); 547 else if(canRead &&!res.canRead()) 548 throw doThrow("no read access to "+label+" ["+res.toString()+"]"); 549 else if(canWrite && !res.canWrite()) 550 throw doThrow("no write access to "+label+" ["+res.toString()+"]"); 551 } 552 } 553 554 private boolean checkDestination(VideoInput vi, VideoOutput destination, String name, int nameconflict) throws PageException { 555 checkFile(destination,"destination", false, false, false); 556 557 // destination 558 if(!Util.isEmpty(name))destination.setResource(destination.getResource().getRealResource(name)); 559 else if(destination.getResource().isDirectory()) { 560 destination.setResource(destination.getResource().getRealResource(vi.getResource().getName())); 561 } 562 563 // escape %d 564 String _name=destination.getResource().getName(); 565 if(_name.indexOf("%d")!=-1) { 566 destination.setResource(destination.getResource().getParentResource().getRealResource(_name.replaceAll("%d", "%%d"))); 567 } 568 569 570 if(destination.getResource().exists() && nameconflict!=NAMECONFLICT_OVERWRITE) { 571 // SKIP 572 if(nameconflict==NAMECONFLICT_SKIP) return false; 573 // MAKEUNIQUE 574 else if(nameconflict==NAMECONFLICT_MAKEUNIQUE) destination.setResource(makeUnique(destination.getResource())); 575 // ERROR 576 else doThrow("destiniation file ["+destination.toString()+"] already exist"); 577 } 578 return true; 579 } 580 581 private Resource makeUnique(Resource res) { 582 583 String ext=getFileExtension(res); 584 String name=getFileName(res); 585 ext=(ext==null)?"":"."+ext; 586 int count=0; 587 while(res.exists()) { 588 res=res.getParentResource().getRealResource(name+(++count)+ext); 589 } 590 return res; 591 } 592 593 /** 594 * get file extension of a file object 595 * @param file file object 596 * @return extnesion 597 */ 598 private static String getFileExtension(Resource file) { 599 String name=file.getName(); 600 int index = name.lastIndexOf('.'); 601 if(index==-1) return null; 602 return name.substring(index+1).trim(); 603 } 604 605 /** 606 * get file name of a file object without extension 607 * @param file file object 608 * @return name of the file 609 */ 610 private static String getFileName(Resource file) { 611 String name=file.getName(); 612 int pos=name.lastIndexOf("."); 613 614 if(pos==-1)return name; 615 return name.substring(0,pos); 616 } 617 618 private VideoProfile getProfile(String strProfile) throws PageException { 619 strProfile=strProfile.trim().toLowerCase(); 620 return getProfileCollection().getProfiles().get(strProfile); 621 } 622 623 private String getProfileKeyList() throws PageException { 624 Iterator<String> it = getProfileCollection().getProfiles().keySet().iterator(); 625 StringBuffer sb=new StringBuffer(); 626 boolean doDel=false; 627 while(it.hasNext()) { 628 if(doDel)sb.append(", "); 629 sb.append(it.next()); 630 doDel=true; 631 } 632 633 return sb.toString(); 634 } 635 636 private PageException doThrow(String message) { 637 return doThrow(message,null); 638 } 639 640 private PageException doThrow(String message, String detail) { 641 if(detail==null)return new ApplicationException(message); 642 return new ApplicationException(message,detail); 643 } 644 645 646 647 648 649 /** 650 * @param width the width to set 651 */ 652 public void setWidth(String strWidth) { 653 this.width = Caster.toIntValue(strWidth,-1); 654 this.strWidth = strWidth; 655 } 656 657 /** 658 * @param height the height to set 659 */ 660 public void setHeight(String strHeight) { 661 this.height = Caster.toIntValue(strHeight,-1); 662 this.strHeight = strHeight; 663 } 664 665 /** 666 * @param audioBitrate the audioBitrate to set 667 * @throws PageException 668 */ 669 public void setAudiobitrate(String audioBitrate) throws PageException { 670 this.audioBitrate = util.toBytes(audioBitrate); 671 } 672 673 /** 674 * @param aspectRatio the aspectRatio to set 675 * @throws PageException 676 */ 677 public void setAspectratio(String strAspectRatio) throws PageException { 678 strAspectRatio=strAspectRatio.trim().toLowerCase(); 679 if("16:9".equals(strAspectRatio)) aspectRatio=VideoProfile.ASPECT_RATIO_16_9; 680 else if("4:3".equals(strAspectRatio)) aspectRatio=VideoProfile.ASPECT_RATIO_4_3; 681 else throw doThrow("invalid aspect ratio definition ["+strAspectRatio+"], valid values are [16:9, 4:3]"); 682 } 683 684 /** 685 * @param framerate the framerate to set 686 */ 687 public void setFramerate(double framerate) { 688 setFps(framerate); 689 } 690 public void setFps(double framerate) { 691 this.framerate = (int) framerate; 692 } 693 694 /** 695 * @param videoBitrate the videoBitrate to set 696 * @throws PageException 697 */ 698 public void setVideobitrate(String videoBitrate) throws PageException { 699 this.videoBitrate = util.toBytes(videoBitrate); 700 } 701 702 /** 703 * @param videoBitrateMin the videoBitrateMin to set 704 * @throws PageException 705 */ 706 public void setVideobitratemin(String videoBitrateMin) throws PageException { 707 this.videoBitrateMin = util.toBytes(videoBitrateMin); 708 } 709 710 /** 711 * @param videoBitrateMax the videoBitrateMax to set 712 * @throws PageException 713 */ 714 public void setVideobitratemax(String videoBitrateMax) throws PageException { 715 this.videoBitrateMax = util.toBytes(videoBitrateMax); 716 } 717 718 /** 719 * @param videoBitrateTolerance the videoBitrateTolerance to set 720 * @throws PageException 721 */ 722 public void setVideobitratetolerance(String videoBitrateTolerance) throws PageException { 723 this.videoBitrateTolerance = util.toBytes(videoBitrateTolerance); 724 } 725 726 /** 727 * @param author the author to set 728 */ 729 public void setAuthor(String author) { 730 this.author = author; 731 } 732 733 /** 734 * @param title the title to set 735 */ 736 public void setTitle(String title) { 737 this.title = title; 738 } 739 740 /** 741 * @param comment the comment to set 742 */ 743 public void setComment(String comment) { 744 this.comment = comment; 745 } 746 747 /** 748 * @param copyright the copyright to set 749 */ 750 public void setCopyright(String copyright) { 751 this.copyright = copyright; 752 } 753 754 /** 755 * @param max the maxFrames to set 756 * @throws PageException 757 */ 758 public void setMax(String strMax) throws PageException { 759 strMax=strMax.trim().toLowerCase(); 760 if(strMax.endsWith("f")) this.maxFrame=Caster.toLongValue(strMax.substring(0,strMax.length()-1)); 761 else if(strMax.endsWith("ms")) this.maxTime=Caster.toDoubleValue(strMax.substring(0,strMax.length()-2))/1000F; 762 else if(strMax.endsWith("s")) this.maxTime=Caster.toDoubleValue(strMax.substring(0,strMax.length()-1)); 763 else setStart(strMax+" ms"); 764 } 765 766 /** 767 * @param result the result to set 768 */ 769 public void setResult(String result) { 770 this.result = result; 771 } 772 773 774 775 /** 776 * @param source1 the source1 to set 777 * @throws PageException 778 */ 779 public void setSource1(String source1) throws PageException { 780 this.source1 = new VideoInputImpl(ResourceUtil.toResourceExisting(pageContext, source1)); 781 } 782 783 784 785 /** 786 * @param source2 the source2 to set 787 * @throws PageException 788 */ 789 public void setSource2(String source2) throws PageException { 790 this.source2 = new VideoInputImpl(ResourceUtil.toResourceExisting(pageContext, source2)); 791 } 792 793 794 795 /** 796 * @param strStart the position to set 797 * @throws PageException 798 */ 799 public void setStart(String strStart) throws PageException { 800 strStart=strStart.trim().toLowerCase(); 801 if(strStart.endsWith("f")) this.startFrame=Caster.toLongValue(strStart.substring(0,strStart.length()-1)); 802 else if(strStart.endsWith("ms")) this.startTime=Caster.toDoubleValue(strStart.substring(0,strStart.length()-2))/1000F; 803 else if(strStart.endsWith("s")) this.startTime=Caster.toDoubleValue(strStart.substring(0,strStart.length()-1)); 804 else setStart(strStart+" ms"); 805 } 806 807 /** 808 * @param videoCodec the videoCodec to set 809 */ 810 public void setVideocodec(String videoCodec) { 811 this.videoCodec = videoCodec; 812 } 813 public void setAudiocodec(String audioCodec) { 814 this.audioCodec = audioCodec; 815 } 816 817 class Pair { 818 Resource res; 819 Struct sct; 820 public Pair(Resource res, Struct sct) { 821 this.res = res; 822 this.sct = sct; 823 } 824 } 825 826 /** 827 * @param audiosamplerate the audiosamplerate to set 828 * @throws PageException 829 */ 830 public void setAudiosamplerate(String sAudiosamplerate) throws PageException { 831 this.audiosamplerate = util.toHerz(sAudiosamplerate); 832 } 833 834 public static void checkRestriction() { 835 836 } 837 838 /** 839 * @param debug the debug to set 840 */ 841 public void setDebug(String debug) { 842 this.debug = debug; 843 } 844 845 /** 846 * @param buffersize the buffersize to set 847 */ 848 public void setBuffersize(double buffersize) { 849 this.buffersize = (long) buffersize; 850 } 851 852 853 public Struct toStruct(VideoInfo[] infos) { 854 Struct sct=new StructImpl(); 855 sct.setEL(KeyConstants._source, toStruct(infos[0])); 856 sct.setEL(KeyConstants._destination, toStruct(infos[1])); 857 return sct; 858 } 859 860 private Struct toStruct(VideoInfo info) { 861 862 Struct sct=info.toStruct(); 863 864 // audio 865 Struct audio=Caster.toStruct(sct.get(AUDIO,null),null); 866 if(audio==null) { 867 audio=new StructImpl(); 868 sct.setEL(AUDIO, audio); 869 } 870 871 // video 872 Struct video=Caster.toStruct(sct.get(VIDEO,null),null); 873 if(video==null) { 874 video=new StructImpl(); 875 sct.setEL(VIDEO, video); 876 } 877 878 // Audio 879 audio.setEL("channels", info.getAudioChannels()); 880 audio.setEL(KeyConstants._codec, info.getAudioCodec()); 881 if(info.getAudioBitrate()!=-1)audio.setEL("bitrate", new Double(info.getAudioBitrate())); 882 if(info.getAudioSamplerate()!=-1)audio.setEL("samplerate", new Double(info.getAudioSamplerate())); 883 884 // Video 885 video.setEL(KeyConstants._codec, info.getVideoCodec()); 886 video.setEL(KeyConstants._format, info.getVideoFormat()); 887 if(info.getVideoBitrate()!=-1)video.setEL("bitrate", new Double(info.getVideoBitrate())); 888 if(info.getFramerate()!=-1)video.setEL("framerate", new Double(info.getFramerate())); 889 890 // Allgemein 891 if(info.getDuration()!=-1)sct.setEL("duration", new Double(info.getDuration())); 892 if(info.getHeight()!=-1)sct.setEL(KeyConstants._height, new Double(info.getHeight())); 893 if(info.getWidth()!=-1)sct.setEL(KeyConstants._width, new Double(info.getWidth())); 894 895 896 897 return sct; 898 } 899 }