Commit 0ffc5b15 authored by petter's avatar petter

Details for video settings

git-svn-id: https://www2.in.tum.de/repos/ttt/trunk@42 0463f305-d864-43cb-8a47-61cf597d4139
parent 5ae81291
......@@ -45,11 +45,13 @@ public class LectureProfile {
private int port = 5900;
private boolean record = true;
private boolean recordVideo = true;
private boolean recordWebcam = true;
private boolean recordLinearAudio = true; // linear = wav
private boolean loopbackRecorder = false;
private int colorDepth = Constants.defaultColorDepth;
private String RecordingCamera;
private ttt.videoRecorder.TTTVideoFormat Format;
private float VideoQuality;
// used whether to show info box or not
// stored in profile because other profile might be used by other person
//
......@@ -101,7 +103,9 @@ public class LectureProfile {
profile.loopbackRecorder = preferences.getBoolean("loopback_recorder", false);
profile.showRecordControlsInfo = preferences.getBoolean("show_record_controls_info", true);
profile.showRecordPlayRecordWarning = preferences.getBoolean("show_record_play_record_warning", true);
profile.RecordingCamera = preferences.get("RecordingCamera", "");
profile.Format = new ttt.videoRecorder.TTTVideoFormat(preferences.getInt("FormatWidth", 160), preferences.getInt("FormatHeight", 120));
profile.VideoQuality = preferences.getFloat("VideoQuality", 0.1f);
return profile;
}
} catch (Exception e) {
......@@ -139,7 +143,10 @@ public class LectureProfile {
preferences.putBoolean("loopback_recorder", loopbackRecorder);
preferences.putBoolean("show_record_controls_info", showRecordControlsInfo);
preferences.putBoolean("show_record_play_record_warning", showRecordPlayRecordWarning);
preferences.put("RecordingCamera", RecordingCamera);
preferences.putFloat("VideoQuality", VideoQuality);
preferences.putInt("FormatWidth", Format.getWidth());
preferences.putInt("FormatHeight", Format.getHeight());
preferences.flush();
} catch (Exception e) {
System.out.println("failed to write Lecture Profile: " + e);
......@@ -486,6 +493,34 @@ public class LectureProfile {
return recordVideo;
}
public void setRecordingFormat (ttt.videoRecorder.TTTVideoFormat format) {
this.Format = format;
}
public String getRecordingCamera(){
return RecordingCamera;
}
public void setRecordingCamera(String recordCameraID) {
this.RecordingCamera = recordCameraID;
}
public ttt.videoRecorder.TTTVideoFormat getVideoFormat(){
return Format;
}
public float getVideoQuality(){
return VideoQuality;
}
public void setVideoQualiy(float Quality){
VideoQuality = Quality;
}
public void setRecordVideoEnabled(boolean recordVideo) {
this.recordVideo = recordVideo;
}
......
......@@ -210,24 +210,23 @@ public class LectureProfileDialog {
recorderCheckBox.setSelected(true);
recorderCheckBox.setEnabled(false);
// video recording
final JCheckBox recordVideoCheckBox = new JCheckBox("incl. video");
recordVideoCheckBox.setToolTipText("enable video recoding");
recordVideoCheckBox.setOpaque(false);
recordVideoCheckBox.setSelected(true);
recordVideoCheckBox.setEnabled(false);
// video recording
final ttt.videoRecorder.VideoSettingPanel CameraSettings = new ttt.videoRecorder.VideoSettingPanel();
CameraSettings.show(false);
JButton CameraSettingsButton = new JButton("Camera Setting");
CameraSettingsButton.setEnabled(false);
CameraSettingsButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
CameraSettings.show(true);
}
});
// cam recording
final JCheckBox camCheckBox = new JCheckBox("incl. Webcam");
camCheckBox.setToolTipText("enable Webcam recoding");
camCheckBox.setOpaque(false);
camCheckBox.setSelected(true);
camCheckBox.setEnabled(false);
// enable/disable according to recorder selection
recorderCheckBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
recordVideoCheckBox.setVisible(recorderCheckBox.isSelected());
filenameField.setVisible(recorderCheckBox.isSelected());
filenameLabel.setVisible(recorderCheckBox.isSelected());
}
......@@ -308,8 +307,8 @@ public class LectureProfileDialog {
panel.add(label);
panel.add(recorderCheckBox);
panel.add(new JLabel(" "));
panel.add(recordVideoCheckBox);
// panel.add(recordVideoCheckBox);
panel.add(filenameLabel);
panel.add(filenameField);
}
......@@ -371,13 +370,12 @@ public class LectureProfileDialog {
videoRecordingPanel.add(Box.createVerticalStrut(5));
label = new JLabel("Video Recording:");
label.setEnabled(false);
videoRecordingPanel.add(label);
final JLabel videolabel = new JLabel("Video Recording:");
videolabel.setEnabled(false);
videoRecordingPanel.add(videolabel);
videoRecordingPanel.add(videoRecordingOnCheckbox);
videoRecordingPanel.add(videoRecordingOffCheckbox);
videoRecordingPanel.add(Box.createVerticalGlue());
videoRecordingPanel.add(CameraSettingsButton);
videoRecordingPanel.add(audioFormatLabel);
videoRecordingPanel.add(wavRadioButton);
......@@ -430,8 +428,6 @@ public class LectureProfileDialog {
portField.setText("5900");
displayDesktopCheckBox.setSelected(false);
recorderCheckBox.setSelected(true);
recordVideoCheckBox.setSelected(true);
recordVideoCheckBox.setVisible(recorderCheckBox.isSelected());
videoRecordingOnCheckbox.setSelected(true);
filenameField.setVisible(recorderCheckBox.isSelected());
filenameLabel.setVisible(recorderCheckBox.isSelected());
......@@ -459,8 +455,9 @@ public class LectureProfileDialog {
// buttons
final JButton okButton = new JButton("ok");
okButton.setEnabled(false);
okButton.setEnabled(false);
JButton cancelButton = new JButton("cancel");
cancelButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
......@@ -544,6 +541,10 @@ public class LectureProfileDialog {
// set values
if (profile != null) {
// CameraSettings.getCameraIDs().contains(profile.getRecordingCamera());
lectureComboBox.setSelectedItem(profile.getLecture());
teacherComboBox.setSelectedItem(profile.getTeacher());
hostField.setText(profile.getHost());
......@@ -562,10 +563,16 @@ public class LectureProfileDialog {
displayDesktopCheckBox.setSelected(!loopback);
recorderCheckBox.setSelected(profile.isRecordEnabled());
recordVideoCheckBox.setSelected(profile.isRecordVideoEnabled());
recordVideoCheckBox.setVisible(recorderCheckBox.isSelected());
// recordVideoCheckBox.setSelected(profile.isRecordVideoEnabled());
// recordVideoCheckBox.setVisible(recorderCheckBox.isSelected());
if(CameraSettings.CamerasFound()){
videoRecordingOnCheckbox.setSelected(profile.isRecordVideoEnabled());
videoRecordingOffCheckbox.setSelected(!profile.isRecordVideoEnabled());
if( CameraSettings.getCameraIDs().contains(profile.getRecordingCamera()))
CameraSettings.setRecordingCamera(profile.getRecordingCamera());
CameraSettings.setRecordingFormat(profile.getVideoFormat());
CameraSettings.setQuality(profile.getVideoQuality());
}
//Always use wave encoding in order to set profile.isRecordLinearAudioEnabled() to true
wavRadioButton.setSelected(true);
mp3RadioButton.setSelected(false);
......@@ -592,11 +599,13 @@ public class LectureProfileDialog {
profile.setPort(portField.getNumber() >= 100 ? portField.getNumber()
: (portField.getNumber() + 5900));
profile.setRecordEnabled(recorderCheckBox.isSelected());
profile.setRecordVideoEnabled(recordVideoCheckBox.isSelected());
profile.setRecordVideoEnabled(videoRecordingOnCheckbox.isSelected());
profile.setRecordLinearAudioEnabled(wavRadioButton.isSelected());
profile.setLoopbackRecorder(!displayDesktopCheckBox.isSelected());
profile.setRecordingFormat(CameraSettings.getRecordingFormat());
profile.setRecordingCamera(CameraSettings.getRecordingCamera());
profile.setVideoQualiy(CameraSettings.getQuality());
CameraSettings.show(false);
profile.storeProfile();
TTT.userPrefs.put("last_used_lecture_profile", profile.getLecture());
......@@ -648,11 +657,17 @@ public class LectureProfileDialog {
for (int i = 0; i < components.length; i++) {
components[i].setEnabled(true);
}
if(CameraSettings.CamerasFound()){
components = videoRecordingPanel.getComponents();
for (int i = 0; i < components.length; i++) {
components[i].setEnabled(true);
}
}else{
videolabel.setText("No Camera available");
videoRecordingOffCheckbox.setSelected(true);
}
avLabel.setEnabled(true);
audioVolumeLabel.setEnabled(true);
recordingPathButton.setEnabled(true);
......
......@@ -61,7 +61,7 @@ public class Recorder implements MessageConsumer, Closeable {
private DataOutputStream out;
private AudioRecorder audioVideoRecorder;
private VideoRecorder VideoRecorder;
private VideoRecorderPanel VideoRecorder;
private LectureProfile lectureProfile;
......@@ -330,14 +330,17 @@ public class Recorder implements MessageConsumer, Closeable {
if (audioVideoRecorder != null)
audioVideoRecorder.startRec(file.getCanonicalPath());
//VideoRecStuff start
// TODO VideoRecStart
//VideoRec start
//TODO recording options
if(lectureProfile.isRecordVideoEnabled()){
VideoRecorder = new VideoRecorder();
VideoRecorder = new VideoRecorderPanel();
VideoRecorder.setRecordingFormat(lectureProfile.getVideoFormat());
VideoRecorder.setRecordingCamera(lectureProfile.getRecordingCamera());
VideoRecorder.setVideoQuality(lectureProfile.getVideoQuality());
VideoRecorder.setRecordpath(file.getCanonicalPath().substring(0, file.getCanonicalPath().length()-4));
VideoRecorder.Start();
}
//VideoRecStuff end
// startime
long starttime = System.currentTimeMillis();
......@@ -414,27 +417,27 @@ public class Recorder implements MessageConsumer, Closeable {
audioVideoRecorder.stopRec();
}
//TODO VideorecStop
if (VideoRecorder != null) {
if (closing) {
if (closing) {
VideoRecorder.close();
VideoRecorder = null;
} else
VideoRecorder = null;
} else{
VideoRecorder.Stop();
}
}
}
out.flush();
out.close();
out = null;
}
TTT.userPrefs.put("last_opened_recording", file.getCanonicalPath());
System.out.println("Recorder stop.");
}
}
// modified by Ziewer - 10.05.2007
// NOTE: writes file header WITHOUT starttime
......
......@@ -37,8 +37,10 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import javax.imageio.ImageIO;
public class ScriptCreator {
final static int HTML_SCRIPT = 1;
......@@ -311,6 +313,9 @@ public class ScriptCreator {
out.close();
}
// css style sheet
void writeStyleSheet() {
try {
......
......@@ -1091,7 +1091,7 @@ public class TTT extends JFrame {
// TODO: position management
private int position;
void addInternalFrameCentered(JInternalFrame frame) {
public void addInternalFrameCentered(JInternalFrame frame) {
frame.pack();
......
package ttt.videoRecorder;
//handles the incoming pictures for linuxcam and windowscam
public interface CaptureInterface {
public void onNewImage(byte[] image, String RecordPath, float Quality);
}
/**
*
* @author sigl ludwig
*
*/
package ttt.videoRecorder;
import java.nio.ByteBuffer;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;
import java.io.File;
import java.lang.Thread;
import javax.swing.ImageIcon;
import com.lti.civil.Image;
import au.edu.jcu.v4l4j.FrameGrabber;
import au.edu.jcu.v4l4j.ImageFormat;
import au.edu.jcu.v4l4j.VideoDevice;
import au.edu.jcu.v4l4j.ResolutionInfo.DiscreteResolution;
import au.edu.jcu.v4l4j.exceptions.V4L4JException;
//This classs set and get methods are completly unfished!
public class LinuxCam implements WebCamControl, Runnable {
public static String RecordPath = "C:\\TTTImplement\\";
private static VideoDevice vd;
private static FrameGrabber fg;
private Thread captureThread;
public static boolean isRecording = false;
public LinuxCam() throws V4L4JException{
String dev = "/dev/video0";
int w=160, h=120, std=0, channel = 0, qty = 60;
initFrameGrabber(dev, w, h, std, channel, qty);
}
/* Shouldn't be needed but untetested...
public void setImage(byte[] b) {
GUIMain.myLabel.setIcon(new ImageIcon(b));
}*/
/**
* is called in start by the new capture thread stuff
*/
public void run(){
ByteBuffer bb;
byte[] b;
try {
//OnCapture.RecordPath = RecordPath;
while(isRecording){
bb = fg.getFrame();
b = new byte[bb.limit()];
bb.get(b);
OnCapture SafePic = new OnCapture();
SafePic.onNewImage((Image) new ImageIcon(b).getImage(),RecordPath);
// setImage(b);
}
} catch (V4L4JException e) {
e.printStackTrace();
System.out.println("Failed to capture image");
}
}
private void initFrameGrabber(String dev, int w, int h, int std, int channel, int qty) throws V4L4JException{
vd = new VideoDevice(dev);
fg = vd.getJPEGFrameGrabber(w, h, channel, std, qty);
}
@Override
public boolean Start() {
private CaptureInterface CI;
private String v4lSysfsPath = "/sys/class/video4linux/";
private String RecordPath;
private List<VideoDevice> system = new LinkedList<VideoDevice>();
private FrameGrabber fg;
private Thread captureThread;
int w = 160, h = 120;
private boolean CamFound = false;
private float CompressionQuality = 0.1f;
public boolean isRecording = false;
String dev = "/dev/video0";
int currentdev = 0;
public LinuxCam() throws V4L4JException {
initializeDevices();
}
protected void initializeDevices() throws V4L4JException {
for (Object i : listV4LDeviceFiles()) {
system.add(new VideoDevice(i.toString()));
}
}
/**
* Implements the capture thread: get a frame from the FrameGrabber, and
* display it
*/
public void run() {
ByteBuffer bb;
byte[] image;
try {
if(!isRecording){
fg.startCapture();
captureThread = new Thread(this, "Capture Thread");
captureThread.start();
isRecording = true;
while (isRecording) {
if (isRecording) {
bb = fg.getFrame();
image = new byte[bb.limit()];
bb.get(image);
CI.onNewImage(image, RecordPath, CompressionQuality);
}
}
} catch (V4L4JException e) {
} catch (V4L4JException e) {
e.printStackTrace();
System.out.println("Failed to capture image");
}
return false;
}
private Object[] listV4LDeviceFiles() {
Vector<String> sdev = new Vector<String>();
File dir = new File(v4lSysfsPath);
String[] files = dir.list();
for (String file : files)
// the following test the presence of "video" in
// each file name - not very portable - relying on HAL
// would be much better ...
if (file.indexOf("video") != -1)
sdev.add("/dev/" + file);
if (sdev.size() != 0) {
CamFound = true;
}
return sdev.toArray();
}
private void initFrameGrabber(int std, int channel, int qty)
throws V4L4JException {
fg = system.get(currentdev)
.getJPEGFrameGrabber(w, h, channel, std, qty);
}
@Override
public boolean Stopp() {
if(isRecording){
fg.stopCapture();
isRecording =false;
// OnCapture.ZipOnStop();
public void release() {
for (VideoDevice x : system) {
x.releaseFrameGrabber();
x.release();
}
}
@Override
public boolean Start() {
if (CamFound)
try {
initFrameGrabber(0, 0, 1);
if (!isRecording) {
fg.startCapture();
captureThread = new Thread(this, "Capture Thread");
isRecording = true;
captureThread.start();
}
} catch (V4L4JException e) {
e.printStackTrace();
}
return false;
}
//returns the intern device id
@Override
public String getDeviceID(int Device) {
try {
return vd.getDeviceInfo().toString();
} catch (V4L4JException e) {
e.printStackTrace();
public boolean Stop() {
if (isRecording) {
captureThread = null;
isRecording = false;
fg.stopCapture();
fg = null;
system.get(currentdev).releaseFrameGrabber();
}
return false;
}
@Override
public String getDeviceID(int Device) {
if (CamFound)
return "/dev/video" + Device;
return null;
}
//it can currently handle only the default cam
@SuppressWarnings("unchecked")
@Override
public List getDeviceList() {
List lista = new LinkedList();
lista.add(vd.getDevicefile());
return lista;
public List<String> getDeviceList() {
List<String> deviselist = new LinkedList<String>();
if (CamFound)
for (VideoDevice i : system) {
try {
deviselist.add(i.getDeviceInfo().getName());
return deviselist;
} catch (V4L4JException e) {
e.printStackTrace();
}
}
return null;
}
@SuppressWarnings("unchecked")
@Override
public List getSupportedFormats(int Device) {
List empty = new LinkedList();
empty.add("Width=160 Height=120");
return empty;
public List<TTTVideoFormat> getSupportedFormats(int Device) {
currentdev = Device;
List<TTTVideoFormat> SupportedFormats = new LinkedList<TTTVideoFormat>();
if (CamFound)
try {
for (ImageFormat i : system.get(Device).getDeviceInfo()
.getFormatList().getJPEGEncodableFormats()) {
if (i.getResolutionInfo().getType().toString().equals(
"DISCRETE")) {
for (DiscreteResolution j : i.getResolutionInfo()
.getDiscreteResolutions()) {
SupportedFormats.add(new TTTVideoFormat(j
.getWidth(), j.getHeight()));
}
}
}
if(!SupportedFormats.isEmpty())
return SupportedFormats;
} catch (V4L4JException e) {
e.printStackTrace();
}
return null;
}
//TODO Implement set Format
@Override
public void setFormat(int Width, int Height) {
w = Width;
h = Height;
}
@Override
public void setSelectedCam(String DeviceID) {
// TODO Auto-generated method stub
dev = DeviceID;
}
@Override
public void setRecordPath(String Path) {
RecordPath = Path;
}
@Override
public void setCaptureInterface(CaptureInterface OnPic) {
CI = OnPic;
}
@Override
public void SetRecordPath(String path) {
RecordPath = path;
public boolean CameraFound() {
return CamFound;
}
@Override
public void setQuality(float Quality) {
if (Quality <= 1.0f && Quality >= 0.1f)
CompressionQuality = Quality;
}
@Override
public float getQuality() {
return CompressionQuality;
}
}
......@@ -7,6 +7,7 @@ import java.util.logging.Logger;
* @author ken lti-Civil
*
*/
// detects the OS (linux/mac/windows)
public final class OSUtils {
@SuppressWarnings("deprecation")
private static final Logger logger = Logger.global;
......@@ -14,13 +15,14 @@ public final class OSUtils {
public static WebCamControl obtainWebcam() {
WebCamControl WBC = null;
String cam = null;
if (OSUtils.isWindows()) {
cam = "ttt.videoRecorder.WindowsCam";
} else
if (OSUtils.isLinux()) {
cam = "ttt.videoRecorder.LinuxCam";
} else {
cam = "ttt.videoRecorder.WindowsCam";
}
try {
Class clazz = Class.forName(cam);
WBC = (WebCamControl) clazz.getConstructors()[0].newInstance(null);
Class<?> clazz = Class.forName(cam);
WBC = (WebCamControl) clazz.getConstructors()[0].newInstance();
} catch (Exception e) {
e.printStackTrace();
}
......
/**
*
* @author sigl ludwig
*
*/
package ttt.videoRecorder;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import javax.swing.ImageIcon;
import com.lti.civil.Image;
import com.lti.civil.awt.AWTImageConverter;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
//
// Gets called every time a new picture is taken. it saves them under the recordpath set direction
//
public class OnCapture {
static private String RecordPath = "C:\\TTTImplement\\";
public static String getRecordPath(){
return OnCapture.RecordPath;
}
public void onNewImage(Image image, String RecordPath)
{
OnCapture.RecordPath = RecordPath;
final BufferedImage bimg;
try
{
bimg = AWTImageConverter.toBufferedImage(image);
}
catch (Exception e)
{ e.printStackTrace();
return;
}
try
{
File ImageFile = new File( RecordPath+".bjpg");