Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 简陋的视频拍摄给定时间的快照_Java_Video_Ffmpeg - Fatal编程技术网

Java 简陋的视频拍摄给定时间的快照

Java 简陋的视频拍摄给定时间的快照,java,video,ffmpeg,Java,Video,Ffmpeg,您好,我正在使用一个视频缩略图。 到目前为止,我已经成功地通过以下方法从一个视频开始拍摄快照 private static Path generateThumbnail(final Path videoFile) throws InterruptedException, IOException { final Demuxer demuxer = Demuxer.make(); demuxer.open(videoFile.toString(), null, false, true

您好,我正在使用一个视频缩略图。 到目前为止,我已经成功地通过以下方法从一个视频开始拍摄快照

private static Path generateThumbnail(final Path videoFile)
     throws InterruptedException, IOException {

 final Demuxer demuxer = Demuxer.make();
 demuxer.open(videoFile.toString(), null, false, true, null, null);

 int streamIndex = -1;
 Decoder videoDecoder = null;
 String rotate = null;
 final int numStreams = demuxer.getNumStreams();
 for (int i = 0; i < numStreams; ++i) {
     final DemuxerStream stream = demuxer.getStream(i);
     final KeyValueBag metaData = stream.getMetaData();
     final Decoder decoder = stream.getDecoder();
     if (decoder != null
             && decoder.getCodecType() == MediaDescriptor.Type.MEDIA_VIDEO) {
         videoDecoder = decoder;
         streamIndex = i;
         rotate = metaData.getValue("rotate", KeyValueBag.Flags.KVB_NONE);
         break;
     }
 }

 if (videoDecoder == null) {
     throw new IOException("Not a valid video file");
 }
 videoDecoder.open(null, null);

 final MediaPicture picture = MediaPicture.make(videoDecoder.getWidth(),
         videoDecoder.getHeight(), videoDecoder.getPixelFormat());

 final MediaPictureConverter converter = MediaPictureConverterFactory
         .createConverter(MediaPictureConverterFactory.HUMBLE_BGR_24, picture);

 final MediaPacket packet = MediaPacket.make();
 BufferedImage image = null;
 MUX : while (demuxer.read(packet) >= 0) {
     if (packet.getStreamIndex() != streamIndex) {
         continue;
     }
     int offset = 0;
     int bytesRead = 0;
     videoDecoder.decodeVideo(picture, packet, offset);
     do {
         bytesRead += videoDecoder.decode(picture, packet, offset);
         if (picture.isComplete()) {
             image = converter.toImage(null, picture);
             break MUX;
         }
         offset += bytesRead;

     } while (offset < packet.getSize());
 }
 if (image == null) {
     throw new IOException("Unable to find a complete video frame");
 }
 if (rotate != null) {
     final AffineTransform transform = new AffineTransform();
     transform.translate(0.5 * image.getHeight(), 0.5 * image.getWidth());
     transform.rotate(Math.toRadians(Double.parseDouble(rotate)));
     transform.translate(-0.5 * image.getWidth(), -0.5 * image.getHeight());
     final AffineTransformOp op = new AffineTransformOp(transform,
             AffineTransformOp.TYPE_BILINEAR);
     image = op.filter(image, null);
 }

 final Path target = videoFile.getParent()
         .resolve(videoFile.getFileName() + ".thumb.jpg");

 final double mul;
 if (image.getWidth() > image.getHeight()) {
     mul = 216 / (double) image.getWidth();
 } else {
     mul = 216 / (double) image.getHeight();
 }

 final int newW = (int) (image.getWidth() * mul);
 final int newH = (int) (image.getHeight() * mul);
 final Image thumbnailImage = image.getScaledInstance(newW, newH,
         Image.SCALE_SMOOTH);
 image = new BufferedImage(newW, newH, BufferedImage.TYPE_INT_BGR);

 final Graphics2D g2d = image.createGraphics();
 g2d.drawImage(thumbnailImage, 0, 0, null);
 g2d.dispose();

 ImageIO.write(image, "jpeg", target.toFile());
 return target.toAbsolutePath(); }
专用静态路径生成缩略图(最终路径视频文件)
抛出InterruptedException,IOException{
final Demuxer Demuxer=Demuxer.make();
open(videoFile.toString(),null,false,true,null,null);
int streamIndex=-1;
解码器videoDecoder=null;
字符串旋转=空;
final int numStreams=demuxer.getNumStreams();
对于(int i=0;i=0){
if(packet.getStreamIndex()!=streamIndex){
继续;
}
整数偏移=0;
int字节读取=0;
视频解码器。解码视频(图片、数据包、偏移量);
做{
字节读取+=视频解码器。解码(图片、数据包、偏移量);
if(picture.isComplete()){
image=converter.toImage(空,图片);
中断多路复用器;
}
偏移量+=字节读取;
}while(offsetimage.getHeight()){
mul=216/(双精度)image.getWidth();
}否则{
mul=216/(双精度)image.getHeight();
}
final int newW=(int)(image.getWidth()*mul);
final int newH=(int)(image.getHeight()*mul);
最终图像thumbnailImage=Image.getScaledInstance(newW,newH,
图像。缩放(平滑);
image=newbufferedimage(newW,newH,BufferedImage.TYPE\u INT\u BGR);
final Graphics2D g2d=image.createGraphics();
g2d.drawImage(thumbnailImage,0,0,null);
g2d.dispose();
write(image,“jpeg”,target.toFile());
返回target.toAbsolutionPath();}
  • 现在,我想做的是在视频开始2秒后拍摄快照,有可能吗?我 尝试使用“Demuxer”-s seek方法,但没有成功


  • 我已经用下面的代码成功地完成了

    这个方法来自图书馆

    public int seek(int stream_index, long min_ts, long ts, long max_ts, int flags);
    
    参数为

    • 流索引用作时基参考的流索引
    • min\u ts可接受的最小时间戳
    • ts目标时间戳
    • 最大\u ts可接受的最大时间戳
    我的实现是

    final int success = demuxer.seek(streamIndex, 0, 700, 99999999,VideoJNI.Demuxer_SEEK_FRAME_get());