/**
* Copyright 2014 Comcast Cable Communications Management, LLC
*
* This file is part of CATS.
*
* CATS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CATS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CATS. If not, see <http://www.gnu.org/licenses/>.
*/
package com.comcast.cats.video.service;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import javax.imageio.ImageIO;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import com.comcast.cats.Settop;
import com.comcast.cats.event.CatsEventDispatcher;
import com.comcast.cats.provider.VideoProvider;
/**
*
* A simple EJB service that can affect the video to a STB based on the path
* to the video device.
*
* @author jtyrre001
*
*/
public class VideoServiceImpl implements VideoProvider
{
private static final long serialVersionUID = 1L;
private static final Logger logger = Logger.getLogger(VideoServiceImpl.class);
private static final String IMAGE_FILE_FORMAT = "jpg";
private static final String DATE_TIME_FORMAT = "yyyy.MM.dd-HH.mm.ss";
/**
*
*/
private Object parentObj;
/**
* VideoController object.
*/
private final VideoController videoController;
/**
* VideoServiceImpl constructor.
* Instantiates an videoController instance.
* @throws MalformedURLException
*/
public VideoServiceImpl(final CatsEventDispatcher dispatcher, final URI videoLocator) throws MalformedURLException
{
if(dispatcher == null || videoLocator == null) {
throw new IllegalArgumentException("CatsEventDispatcher and Video Locator must not be null");
}
this.videoController = new VideoController(dispatcher, videoLocator, this);
}
/**
* Returns an ArrayList of available video sizes retrieved from the Axis Device.
* First column is resolution id: D1, 4CIF, CIF etc.
* Second column is resolution: 720 x 480 etc.
*
* @return vidSizelist Table list of all available video sizes
*/
public List<String> getAvailableVideoSizes()
{
return (List<String>) videoController.getAvailableVideoSizes();
}
/**
* Sets the video size requested by the client.
*
* @param vidSize Video Size / dimension of screen.
*/
public void setVideoSize(final Dimension vidSize)
{
this.videoController.setVideoDimension(vidSize);
if(this.videoController.isConnected()) {
try {
this.videoController.connect();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* Sets the frame read rate from the incoming stream.
*
* @param fps frame rate in frames/per second
*/
public void setFrameRate(final Integer fps)
{
videoController.setFrameRate(fps);
}
/**
* Returns the frame read rate from the incoming stream.
*
* @return rate frame rate in frames/per second
*/
public Integer getFrameRate()
{
return videoController.getFrameRate();
}
/**
* Returns the current video streaming dimensions.
*/
@Override
public Dimension getVideoSize() {
return videoController.getVideoDimension();
}
/**
* Returns the URI of the Axis Server device.
*
* @return URI axis server URI
*/
public URI getVideoLocator()
{
return videoController.getVideoLocator();
}
/**
* Returns streaming status of server true or false.
*
* @return videoController.isStreaming()
*/
public boolean isStreaming()
{
return this.videoController.isStreaming();
}
/**
* Returns connect status to Axis Server true or false.
*
* @return videoController.isConnected()
*/
public boolean isConnected()
{
return this.videoController.isConnected();
}
/**
* Makes the HTTP connection to the Axis Server device.
*/
public void connectVideoServer()
{
try
{
videoController.connect();
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
}
/**
* Disconnects from the Axis Server device.
* Note: A disconnect automatically stop streaming video.
*/
public void disconnectVideoServer()
{
this.videoController.disconnectFromAxisDevice();
}
/**
* Gets a still video image from the Axis Camera.
*
* @return BufferedImage
*/
@Override
public BufferedImage getVideoImage() {
return this.videoController.getImage();
}
/**
* Gets a still video image from the Axis Camera.
*
* @return BufferedImage
*/
@Override
public BufferedImage getVideoImage(Dimension dim) {
return this.videoController.getImage(dim);
}
public void setParent(Object parent) {
this.parentObj = parent;
}
@Override
public Object getParent() {
return this.parentObj;
}
@Override
public String getVideoURL()
{
return videoController.getURL();
}
@Override
public String saveVideoImage()
{
String fileLocation = null;
String catsHome = System.getProperty( "cats.home" );
if( null != catsHome ){
fileLocation = catsHome + System.getProperty( "file.separator" ) + getFolderAndFileName();
saveVideoImage(fileLocation);
}
else
{
logger.error("CATS HOME is not set. Saving Image cannot continue");
}
return fileLocation;
}
@Override
public void saveVideoImage( String filePath )
{
if( null == filePath || filePath.isEmpty() )
{
logger.error( "Saving video image failed. The file location cannot be null or empty: " + filePath );
}
else
{
String imagePath = filePath;
File imagefile = new File( imagePath );
// If the file path specified is a relative path, the image must be saved in to CATS_HOME/$macFolder/<filePath>
if( !imagefile.isAbsolute() )
{
String catsHome = System.getProperty( "cats.home" );
if( null != catsHome )
{
imagePath = catsHome + System.getProperty( "file.separator" ) + getCleanMac() +
System.getProperty( "file.separator" )+ imagePath;
}
imagefile = new File( imagePath );
}
/**
* If the specified file path is of an existing directory, the image will be saved in to
* <filepath>/$macFolder/$defaultFileName.jpg
*/
if( imagefile.exists() && imagefile.isDirectory() )
{
imagePath = imagePath + System.getProperty( "file.separator" ) + getFolderAndFileName();
imagefile = new File( imagePath );
}
try
{
FileUtils.forceMkdir( imagefile.getAbsoluteFile().getParentFile() );
ImageIO.write( getVideoImage(), IMAGE_FILE_FORMAT, imagefile );
logger.info( "Saved video image to file: " + imagefile.getAbsolutePath() );
}
catch (Exception e)
{
logger.error( "Saving video image failed. Error in creating file: '" + imagePath + "'.\n" + e.getMessage() );
}
}
}
private String getFolderAndFileName()
{
Date date = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat( DATE_TIME_FORMAT );
String dateString = dateFormat.format( date );
return getCleanMac() + System.getProperty( "file.separator" ) + dateString + "." + IMAGE_FILE_FORMAT;
}
private String getCleanMac()
{
String cleanMac = "";
if( null != getParent() )
{
try
{
Settop settop = (Settop) getParent();
String hostMacAddress = settop.getHostMacAddress();
cleanMac = hostMacAddress.trim().replace( ":", "" ).toUpperCase();
}
catch(ClassCastException e)
{
logger.error( "VideoProvider doesn't have a parent settop." );
}
}
return cleanMac;
}
}