001/******************************************************************************* 002 * Copyright (c) 2024, 2026, Olivier Ayache. All rights reserved. 003 * 004 * This file is part of AVPKit. 005 * 006 * AVPKit is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU Lesser General Public License as published by 008 * the Free Software Foundation, either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * AVPKit is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public License 017 * along with AVPKit. If not, see <http://www.gnu.org/licenses/>. 018 *******************************************************************************/ 019 020package com.avpkit.mediatool.demos; 021 022import javax.swing.JFrame; 023 024import com.avpkit.mediatool.IMediaReader; 025import com.avpkit.mediatool.ToolFactory; 026import com.avpkit.core.IError; 027import com.avpkit.core.IMetaData; 028import com.avpkit.core.IContainer; 029import com.avpkit.core.IContainerFormat; 030 031 032/** 033 * Using {@link IMediaReader}, takes a FFMPEG device driver name (ex: 034 * "video4linux2"), and a device name (ex: /dev/video0), and displays 035 * video from that device. For example, a web camera. 036 * 037 * <p> For example, to play the default camera on these operating 038 * systems: <ul> <li>Microsoft Windows:<pre>java -cp 039 * %XUGGLE_HOME%\share\java\jars\avpkit-core.jar 040 * com.avpkit.mediatool.demos.DisplayWebcamVideo vfwcap 0</pre></li> 041 * <li>Linux:<pre>java -cp 042 * $XUGGLE_HOME/share/java/jars/avpkit-core.jar 043 * com.avpkit.mediatool.demos.DisplayWebcamVideo video4linux2 044 * /dev/video0</pre></li> </ul> </p> 045 * 046 * @author aclarke 047 * @author trebor 048 */ 049 050public class DisplayWebcamVideo 051{ 052 /** 053 * Takes a FFMPEG webcam driver name, and a device name, opens the 054 * webcam, and displays its video in a Swing window. 055 * <p> 056 * Examples of device formats are: 057 * </p> 058 * <table border="1"> 059 * <thead> 060 * <tr> 061 * <td>OS</td> 062 * <td>Driver Name</td> 063 * <td>Sample Device Name</td> 064 * </tr> 065 * </thead> 066 * <tbody> 067 * <tr> 068 * <td>Windows</td> 069 * <td>vfwcap</td> 070 * <td>0</td> 071 * </tr> 072 * <tr> 073 * <td>Linux</td> 074 * <td>video4linux2</td> 075 * <td>/dev/video0</td> 076 * </tr> 077 * </tbody> 078 * </table> 079 * 080 * <p> 081 * Webcam support is very limited; you can't query what devices are 082 * available, nor can you query what their capabilities are without 083 * actually opening the device. Sorry, but that's how FFMPEG rolls. 084 * </p> 085 * 086 * @param args Must contain two strings: a FFMPEG driver name and a 087 * device name (which is dependent on the FFMPEG driver). 088 */ 089 090 public static void main(String[] args) 091 { 092 if (args.length != 2) 093 throw new IllegalArgumentException( 094 "must pass in a driver name and a device name"); 095 096 // create a new mr. display webcam video 097 098 new DisplayWebcamVideo(args[0], args[1]); 099 } 100 101 /** Construct a DisplayWebcamVideo which reads and plays a video 102 * from an attached webcam. 103 * 104 * @param driverName the name of the webcan drive 105 * @param deviceName the name of the webcan device 106 */ 107 108 public DisplayWebcamVideo(String driverName, String deviceName) 109 { 110 // create a AVPKit container object 111 112 IContainer container = IContainer.make(); 113 114 // tell AVPKit about the device format 115 116 IContainerFormat format = IContainerFormat.make(); 117 if (format.setInputFormat(driverName) < 0) 118 throw new IllegalArgumentException( 119 "couldn't open webcam device: " + driverName); 120 121 // devices, unlike most files, need to have parameters set in order 122 // for AVPKit to know how to configure them, for a webcam, these 123 // parameters make sense 124 125 IMetaData params = IMetaData.make(); 126 127 params.setValue("framerate", "30/1"); 128 params.setValue("video_size", "320x240"); 129 130 // open the container 131 132 int retval = container.open(deviceName, IContainer.Type.READ, format, 133 false, true, params, null); 134 if (retval < 0) 135 { 136 // this little trick converts the non friendly integer return 137 // value into a slightly more friendly object to get a 138 // human-readable error name 139 140 IError error = IError.make(retval); 141 throw new IllegalArgumentException( 142 "could not open file: " + deviceName + "; Error: " + 143 error.getDescription()); 144 } 145 146 // create a media reader to wrap that container 147 148 IMediaReader reader = ToolFactory.makeReader(container); 149 150 // Add a media viewer that will display the video, but that exits 151 // the JVM when it is destroyed 152 reader.addListener(ToolFactory.makeViewer(true, JFrame.EXIT_ON_CLOSE)); 153 154 // read out the contents of the media file, note that nothing else 155 // happens here. action happens in the onVideoPicture() method 156 // which is called when complete video pictures are extracted from 157 // the media source. Since we're reading from a web cam this 158 // loop will never return, but if the window is closed, the JVM is 159 // exited. 160 161 while (reader.readPacket() == null) 162 do {} while(false); 163 164 } 165 166}