/*
* Copyright 2012 buddycloud
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.buddycloud.mediaserver.business.util;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Arrays;
import com.xuggle.xuggler.ICodec;
import com.xuggle.xuggler.IContainer;
import com.xuggle.xuggler.IPacket;
import com.xuggle.xuggler.IStream;
import com.xuggle.xuggler.IStreamCoder;
import com.xuggle.xuggler.IVideoPicture;
import com.xuggle.xuggler.io.IURLProtocolHandler;
import com.xuggle.xuggler.video.ConverterFactory;
import com.xuggle.xuggler.video.IConverter;
public class VideoUtils {
public static final String PREVIEW_MIME_TYPE = "image/jpeg";
public static final String PREVIEW_TYPE = "jpg";
private IContainer container;
private IStreamCoder coder;
private Integer videoStreamIndex;
private Long videoLength;
public VideoUtils(File video) {
start(video);
}
private void start(File video) {
this.container = IContainer.make();
if (container.open(video.getAbsolutePath(), IContainer.Type.READ, null) >= 0) {
int numStreams = container.getNumStreams();
for (int i = 0; i < numStreams; i++) {
IStream stream = container.getStream(i);
IStreamCoder coder = stream.getStreamCoder();
if (coder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) {
this.coder = coder;
this.videoLength = stream.getDuration();
this.videoStreamIndex = i;
break;
}
}
}
}
public Long getVideoLength() {
return this.videoLength != null ? this.videoLength : null;
}
public Integer getVideoHeight() {
return this.coder != null ? this.coder.getHeight() : null;
}
public Integer getVideoWidth() {
return this.coder != null ? this.coder.getWidth() : null;
}
@SuppressWarnings("deprecation")
public BufferedImage createVideoPreview(int width, int height) {
if (coder != null && videoLength != null) {
if (coder.open() >= 0) {
IPacket packet = IPacket.make();
container.seekKeyFrame(videoStreamIndex, videoLength / 2,
IURLProtocolHandler.SEEK_SET);
int nBytesRead = container.readNextPacket(packet);
while (packet.getStreamIndex() != videoStreamIndex) {
nBytesRead = container.readNextPacket(packet);
}
IVideoPicture picture = IVideoPicture.make(
coder.getPixelType(), coder.getWidth(),
coder.getHeight());
while (!picture.isComplete()) {
coder.decodeVideo(picture, packet, nBytesRead);
}
IConverter converter = ConverterFactory.createConverter(
ConverterFactory.XUGGLER_BGR_24, picture);
BufferedImage image = converter.toImage(picture);
return ImageUtils.createImagePreview(image, width, height);
}
}
return null;
}
public static boolean isVideo(String extension) {
if (null == extension) {
return false;
}
return Arrays.binarySearch(FORMATS, extension.toLowerCase()) >= 0;
}
private static final String[] FORMATS = { "264", "3g2", "3gp", "3gp2",
"3gpp", "3gpp2", "3mm", "3p2", "60d", "787", "890", "aaf", "aep",
"aepx", "aet", "aetx", "ajp", "ale", "am", "amc", "amv", "amx",
"anim", "arcut", "arf", "asf", "asx", "avb", "avd", "avi", "avp",
"avs", "avs", "axm", "bdm", "bdmv", "bdt2", "bdt3", "bik", "bin",
"bix", "bmk", "bnp", "box", "bs4", "bsf", "byu", "camproj",
"camrec", "camv", "cel", "cine", "cip", "clpi", "cmmp", "cmmtpl",
"cmproj", "cmrec", "cpi", "cst", "cvc", "d2v", "d3v", "dat", "dav",
"dce", "dck", "dcr", "dcr", "ddat", "dif", "dir", "divx", "dlx",
"dmb", "dmsd", "dmsd3d", "dmsm", "dmsm3d", "dmss", "dmx", "dnc",
"dpa", "dpg", "dream", "dsy", "dv", "dv-avi", "dv4", "dvdmedia",
"dvr", "dvr-ms", "dvx", "dxr", "dzm", "dzp", "dzt", "edl", "evo",
"eye", "ezt", "f4p", "f4v", "fbr", "fbr", "fbz", "fcp",
"fcproject", "flc", "flh", "fli", "flv", "flx", "gfp", "gl", "gom",
"grasp", "gts", "gvi", "gvp", "h264", "hdmov", "hkm", "ifo",
"imovieproj", "imovieproject", "ircp", "irf", "ism", "ismc",
"ismv", "iva", "ivf", "ivr", "ivs", "izz", "izzy", "jss", "jts",
"jtv", "k3g", "lrec", "lsf", "lsx", "m15", "m1pg", "m1v", "m21",
"m21", "m2a", "m2p", "m2t", "m2ts", "m2v", "m4e", "m4u", "m4v",
"m75", "meta", "mgv", "mj2", "mjp", "mjpg", "mk3d", "mkv", "mmv",
"mnv", "mob", "mod", "modd", "moff", "moi", "moov", "mov", "movie",
"mp21", "mp21", "mp2v", "mp4", "mp4v", "mpe", "mpeg", "mpeg4",
"mpf", "mpg", "mpg2", "mpgindex", "mpl", "mpls", "mpsub", "mpv",
"mpv2", "mqv", "msdvd", "mse", "msh", "mswmm", "mts", "mtv", "mvb",
"mvc", "mvd", "mve", "mvex", "mvp", "mvp", "mvy", "mxf", "mys",
"ncor", "nsv", "nuv", "nvc", "ogm", "ogv", "ogx", "osp", "pac",
"par", "pds", "pgi", "photoshow", "piv", "playlist", "plproj",
"pmf", "pmv", "pns", "ppj", "prel", "pro", "prproj", "prtl", "psh",
"pssd", "pva", "pvr", "pxv", "qt", "qtch", "qtl", "qtm", "qtz",
"r3d", "rcd", "rcproject", "rdb", "rec", "rm", "rmd", "rmd", "rmp",
"rms", "rmv", "rmvb", "roq", "rp", "rsx", "rts", "rts", "rum",
"rv", "rvl", "sbk", "sbt", "scc", "scm", "scm", "scn",
"screenflow", "sec", "seq", "sfd", "sfvidcap", "siv", "smi", "smi",
"smil", "smk", "sml", "smv", "spl", "sqz", "srt", "ssm", "stl",
"str", "stx", "svi", "swf", "swi", "swt", "tda3mt", "tdx", "tivo",
"tix", "tod", "tp", "tp0", "tpd", "tpr", "trp", "ts", "tsp", "tvs",
"usm", "vc1", "vcpf", "vcr", "vcv", "vdo", "vdr", "vdx", "veg",
"vem", "vep", "vf", "vft", "vfw", "vfz", "vgz", "vid", "video",
"viewlet", "viv", "vivo", "vlab", "vob", "vp3", "vp6", "vp7",
"vpj", "vro", "vs4", "vse", "vsp", "w32", "wcp", "webm", "wlmp",
"wm", "wmd", "wmmp", "wmv", "wmx", "wot", "wp3", "wpl", "wtv",
"wvx", "xej", "xel", "xesc", "xfl", "xlmv", "xvid", "yuv", "zm1",
"zm2", "zm3", "zmv" };
}