package resa.evaluation.tools; import org.bytedeco.javacpp.opencv_core; import org.bytedeco.javacv.FFmpegFrameGrabber; import org.bytedeco.javacv.FrameGrabber; import redis.clients.jedis.Jedis; import resa.util.ConfigUtil; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.file.Files; import java.util.*; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.stream.Collectors; import java.util.stream.IntStream; import static org.bytedeco.javacpp.opencv_highgui.cvSaveImage; /** * Created by ding on 14-3-18. */ public class ImageSender { private static final File END = new File("END"); private String host; private int port; private byte[] queueName; private BlockingQueue<File> dataQueue = new ArrayBlockingQueue<>(10000); public ImageSender(Map<String, Object> conf) { this.host = (String) conf.get("redis.host"); this.port = ((Number) conf.get("redis.port")).intValue(); this.queueName = ((String) conf.get("redis.queue")).getBytes(); } public void send2Queue(String videoFile, int fps, int retain) throws IOException { List<Integer> array = new ArrayList(IntStream.range(0, fps).boxed().collect(Collectors.toList())); for (int i = 0; i < 3; i++) { new PushThread().start(); } Random rand = new Random(); int range = Math.min(fps - retain, retain); FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(videoFile); try { grabber.start(); // opencv_core.IplImage img = null; long now; Set<Integer> retainFrames = new HashSet<>(); while (true) { Collections.shuffle(array); int count = retain + (int) ((2 * rand.nextDouble() - 1) * range); retainFrames.clear(); for (int j = 0; j < count; j++) { retainFrames.add(array.get(j)); } now = System.currentTimeMillis(); System.out.println(count + "@" + now + ", qLen=" + dataQueue.size()); for (int j = 0; j < fps; j++) { opencv_core.IplImage source = grabber.grab(); if (retainFrames.contains(j)) { // if (img == null) { // opencv_core.CvSize size = cvSize((int) (source.width() / 1.5), // (int) (source.height() / 1.5)); // img = opencv_core.IplImage.create(size, source.depth(), source.nChannels()); // } // cvResize(source, img); File imgFile = File.createTempFile("img-", ".jpg"); cvSaveImage(imgFile.getAbsolutePath(), source); dataQueue.put(imgFile); } } long sleep = now + 1000 - System.currentTimeMillis(); if (sleep > 0) { Thread.sleep(sleep); } } } catch (Exception e) { e.printStackTrace(); } finally { try { grabber.release(); } catch (FrameGrabber.Exception e) { e.printStackTrace(); } } } private class PushThread extends Thread { private Jedis jedis = new Jedis(host, port); private PushThread() { } @Override public void run() { File f; try { while ((f = dataQueue.take()) != END) { try { jedis.rpush(queueName, Files.readAllBytes(f.toPath())); } catch (IOException e) { } finally { f.delete(); } } } catch (InterruptedException e) { e.printStackTrace(); } finally { dataQueue.offer(END); } } } public static void main(String[] args) throws Exception { if (args.length < 4) { System.out.println("usage: ImageSender <confFile> <videoFile> <fps> <retain>"); return; } ImageSender sender = new ImageSender(ConfigUtil.readConfig(new File(args[0]))); if (!new File(args[1]).exists()) { throw new FileNotFoundException(args[1]); } System.out.println("start sender"); sender.send2Queue(args[1], Integer.parseInt(args[2]), Integer.parseInt(args[3])); System.out.println("end sender"); } }