sarxos / webcam-capture

The goal of this project is to allow integrated or USB-connected webcams to be accessed directly from Java. Using provided libraries users are able to read camera images and detect motion. Main project consist of several sub projects - the root one, which contains required classes, build-in webcam driver compatible with Windows, Linux and Mac OS, which can stream images as fast as your camera can serve them (up to 50 FPS). Main project can be used standalone, but user is able to replace build-in driver with different one - such as OpenIMAJ, GStreamer, V4L4j, JMF, LTI-CIVIL, FMJ, etc.
http://webcam-capture.sarxos.pl
MIT License
2.26k stars 1.11k forks source link

No image available after turning camera off then turning back on. #528

Open jarielbalberona opened 7 years ago

jarielbalberona commented 7 years ago

Good day sarxos, I have a problem with me project. When running the project, camera is working just fine. I have a button to turn on/off the camera, if turned on the numpad is enabled and if off, numpad is disabled and camera will be enabled, but after turning on back the camera, the panel displays "No image available" but it can still capture bar codes, it has just no display. Hope you can help me, thank you. 6 7

pavlovaleksei commented 7 years ago

I was faced with the same problem

//Class StartRecorder
package recorder;

import com.github.sarxos.webcam.Webcam;

/**
 * Created by a.pavlov on 03.03.2017.
 */
public class StartRecord {
    public static void main(String[] args) {
        Start st = new Start();
       // Webcam cam = Webcam.getDefault();
        for (int i = 0; i < 3; i++) {

            st.m();

        }

        System.out.println("RECORDING IS STOP!\nFILE SAVE!");
        while (true){

        }
    }
}

//class Start
package recorder;

import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamEvent;
import com.github.sarxos.webcam.WebcamLock;
import com.github.sarxos.webcam.ds.buildin.WebcamDefaultDriver;
import com.xuggle.xuggler.Xuggler;

import javax.swing.*;

/**
 * Created by a.pavlov on 01.03.2017.
 *
 * @version 1.2
 */
public class Start{

    public void m() {

        //Экземпляр класса Recorder
        Recorder record = new Recorder();

        //Указываем адрес сохранения видеофайла
        record.setFilePath("C:/Pavlov/Java/projects/projects_in_idea/media/test1/");
        //Указываем кол-во проходов цикла (1 проход = 1 сек.)
        record.setRecordTime(1);
        //Вызываем метод записи
        try {
            record.record();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //Выводим результаты работы в консоль
        System.out.println("===================================================================================");
        System.out.println("Запись успешно завершена, файл сохранен!");
        System.out.println("Общее кол-во проходов = " + record.count);
        System.out.println("===================================================================================");

return;
        //Вывод диалогового окна по завершению
        //JOptionPane.showMessageDialog(null, "Запись успешно завершена, файл сохранен!\nОбщее кол-во проходов = " + record.count);
    }

}

//class Recorder
package recorder;

import com.github.sarxos.webcam.*;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;

import com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice;
import com.xuggle.mediatool.IMediaWriter;
import com.xuggle.mediatool.ToolFactory;
import com.xuggle.xuggler.*;
import com.xuggle.xuggler.IAudioSamples.Format;
import com.xuggle.xuggler.video.ConverterFactory;
import com.xuggle.xuggler.video.IConverter;

import java.util.Calendar;
import java.util.List;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.TargetDataLine;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

/**
 * Created by a.pavlov on 01.03.2017.
 *
 * @version 1.2
 */
public class Recorder {

    //Синхронизация времени начала записи потоков аудио и видео
    public static long start = System.currentTimeMillis() + 5000;
    //Создаем кодировщик
    public static IMediaWriter writer;

    //Настройка времени записи и частоты кадров
    public static int record_time = 10;
    public static int fps = 10;

    //Переменные для настройки качесва записи звука (кол-во каналов, частота в Hz)
    public static final int CHANNEL_COUNT = 2;
    public static final int SAMPLE_RATE = 22050;

    //Переменные для настройки формата записи аудио
    private static final Format soundFormat = Format.FMT_S16;
    private static final int BYTE_DEPTH = soundFormat.swigValue() + 1;
    private static final int BIT_DEPTH = 8 * BYTE_DEPTH;

    //Переменные времени, линии и формата записи аудио
    private static int audioTime = 0;
    private static TargetDataLine audioLine = null;
    private static AudioFormat audioFormat = null;

    //Переменная для указания кол-ва проходов (1 проход = 10сек.)
    private static int recordTime = 0;

    public static void setRecordTime(int recordTime) {
        Recorder.recordTime = recordTime;
    }

    //Переменная для подсчета кол-ва проходов цикла записи видеофайла
    protected int count;

    //Переменная пути сохранения файла
    private String filePath = null;

    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }

    /**
     * Метод указания имени записывающегося файла
     *
     * @return String fileName
     */
    private String fileRenamed() {
        //Экзаемпляр класса Calendar
        Calendar calendar = Calendar.getInstance();
        //Задаем имя получаемого файла
        String fileName = calendar.get(Calendar.DAY_OF_MONTH) + "d"
                + calendar.get(Calendar.HOUR_OF_DAY) + "h"
                + calendar.get(Calendar.MINUTE) + "m"
                + calendar.get(Calendar.SECOND) + "s.";
        return fileName;
    }

    /**
     * Метод записи видеофайла
     */
    public void record() throws InterruptedException {

        //Создаем окно
        JFrame window = new JFrame("Веб-камера");
        window.setVisible(true);   //При true окно активно

        //К имени файла добавляем его расширение
        File file = new File(filePath + fileRenamed() + "mp4");

        //Добавляем в список доступные камеры
        List<Webcam> list = Webcam.getWebcams();

        //Проверяем доступные камеры, подключаемся к камере по умолчанию
        for (int i = 0; i < list.size(); i++) {
            try {
                Webcam cam = list.get(i);
                cam.getDevice();
                System.out.println("Используется камера: " + cam.getName());
                BufferedImage image = cam.getImage();
            } catch (Exception ex) {
                System.out.println("Ошибка камеры: " + i + "===" + ex);
            }
        }

        //Указываем транскодеру, куда кодировать видео
        writer = ToolFactory.makeWriter(filePath + file.getName());

        /*
        Задаем разрешение записи:
        QQVGA = 176 x 144
        QVGA = 320 x 240
        VGA = 640 x 480
        */
        Dimension size = WebcamResolution.QQVGA.getSize();

        //Открываем доступную камеру

        Webcam webcam = Webcam.getDefault();
        webcam.setViewSize(size);
        webcam.open();

        System.out.println("Камера открыта? ====== " + webcam.isOpen());

        //Добавляем аудио и видеопотоки (указываем кодек для кодирования)
        writer.addVideoStream(0, 0, ICodec.ID.CODEC_ID_H264, size.width, size.height);
        writer.addAudioStream(1, 0, ICodec.ID.CODEC_ID_AAC, 2, 22050);

        //Начинаем аудиозапись
        try {
            openAudioRec();
        } catch (LineUnavailableException ex) {
            System.out.println("Ошибка записи: " + ex);
        }

        //*********************     Цикл для записи видеофайла по указанному времени        *******************/

        for (int step = 0; step < recordTime; step++) {
            System.out.println("Проход № " + step);
            count++;

            //В цикле производим снимки экрана
            for (int i = 0; i < 100; i++) {

                System.out.println("Кадр № " + i);

                //Записываем снимки экрана в BufferedImage

                BufferedImage image = ConverterFactory.convertToType(webcam.getImage(), BufferedImage.TYPE_3BYTE_BGR);
                IConverter converter = ConverterFactory.createConverter(image, IPixelFormat.Type.YUV420P);

                //Создаем фрейм. В конвертере указываем что, и с какой скоростью конвертировать
                IVideoPicture frame = converter.toPicture(image, (System.currentTimeMillis() - start) * 1000);
                frame.setKeyFrame(i == 0);
                frame.setQuality(0);

                //Начинаем кодирование аудио и видео
                writer.encodeVideo(0, frame);
                writer.encodeAudio(1, getAudioSamples(fps));

                //Настройки для окна
                window.setSize(size.width, size.height);    //Размер окна зависит от разрешения записи
                window.getContentPane().removeAll();
                window.getContentPane().add(new JLabel(new ImageIcon(image)));
                window.getContentPane().validate();
                window.getContentPane().invalidate();
                window.getContentPane().repaint();

            }

        }

        //****************     Окончание цикла для записи видеофайла по указанному времени        ******************/

        //Закрываем кодирование аудио и видео

        closeAudioRec();
        writer.close();
        window.dispose();
        webcam.close();

        System.out.println("Видео сохранено в файл: " + file.getAbsolutePath());
        //Вызываем метод определения размера файла
        fileSize(file);
        return;

    }

    /**
     * Метод определения размера файла
     *
     * @param file
     */
    private void fileSize(File file) {
        if (file.length() <= 0) {
            System.out.println("Ошибка файла! Размер файла " + file.length() + " не может быть меньше 0!");
        } else if (file.length() > 0 && file.length() < 10e2) {
            System.out.println("Размер файла составляет: " + file.length() + "b");
        } else if (file.length() >= 10e2 && file.length() < 10e5) {
            double kb = file.length() / 10e2;
            System.out.println("Размер файла составляет: " + kb + "kb");
        } else if (file.length() >= 10e5 && file.length() < 1000000000L) {
            double mb = file.length() / 10e5;
            System.out.println("Размер файла составляет: " + mb + "mb");
        } else if (file.length() >= 1000000000L && file.length() < 1000000000000L) {
            double gb = file.length() / 1000000000L;
            System.out.println("Размер файла составляет: " + gb + "Gb");
        } else
            System.out.println("Файл слишком велик...");
    }

    /**
     * Метод установки формата аудио. Возвращает audioFormat
     *
     * @return
     */
    private static AudioFormat getAudioFormat() {
        if (audioFormat == null) {
            audioFormat = new AudioFormat(SAMPLE_RATE, BIT_DEPTH, CHANNEL_COUNT, true, false);
        }
        return audioFormat;
    }

    /**
     * Метод начала записи аудио
     *
     * @throws LineUnavailableException
     */
    public static void openAudioRec() throws LineUnavailableException {
        DataLine.Info info = new DataLine.Info(TargetDataLine.class, getAudioFormat());
        //Создаем и открываем аудиолинию
        audioLine = (TargetDataLine) AudioSystem.getLine(info);
        audioLine.open(getAudioFormat());
        audioTime = 1;
    }

    /**
     * Метод указания настроек кодирования аудио
     *
     * @param fps
     * @return
     */
    public static IAudioSamples getAudioSamples(int fps) {

        //Проверяем частоту кадров
        if (fps <= 0) {
            fps = 1;
        }

        IAudioSamples samples = IAudioSamples.make(SAMPLE_RATE / fps, CHANNEL_COUNT, soundFormat);
        audioLine.start();
        byte[] data = new byte[(SAMPLE_RATE * BYTE_DEPTH * CHANNEL_COUNT) / fps];
        int sz = audioLine.read(data, 0, data.length);
        samples.put(data, 0, 0, sz);
        audioTime += (sz);

        samples.setComplete(true, sz / (BYTE_DEPTH * CHANNEL_COUNT), SAMPLE_RATE, CHANNEL_COUNT, soundFormat,
                audioTime / (BYTE_DEPTH * CHANNEL_COUNT));

        return samples;
    }

    /**
     * Метод окончания записи аудио
     */
    public static void closeAudioRec() {
        if (audioLine != null) {
            audioLine.close();
            audioLine = null;
        }
    }

}
pavlovaleksei commented 7 years ago

win 7 x64 Thank you!