001/** 002 * Copyright (c) 2011, The University of Southampton and the individual contributors. 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without modification, 006 * are permitted provided that the following conditions are met: 007 * 008 * * Redistributions of source code must retain the above copyright notice, 009 * this list of conditions and the following disclaimer. 010 * 011 * * Redistributions in binary form must reproduce the above copyright notice, 012 * this list of conditions and the following disclaimer in the documentation 013 * and/or other materials provided with the distribution. 014 * 015 * * Neither the name of the University of Southampton nor the names of its 016 * contributors may be used to endorse or promote products derived from this 017 * software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030/** 031 * 032 */ 033package org.openimaj.video.timecode; 034 035import java.util.regex.Matcher; 036import java.util.regex.Pattern; 037 038/** 039 * A timecode representation that extends the standard frame count representation 040 * to provide hours, minutes, seconds and frames timecode. 041 * 042 * @author David Dupplaw (dpd@ecs.soton.ac.uk) 043 * 044 * @created 6 Jun 2011 045 */ 046public class HrsMinSecFrameTimecode extends FrameNumberVideoTimecode 047{ 048 /** 049 * Default constructor that takes the current (start) frame number 050 * and the number of frames in one second. 051 * 052 * @param number The frame number. 053 * @param framesPerSec The number of frames per second. 054 */ 055 public HrsMinSecFrameTimecode( final long number, final double framesPerSec ) 056 { 057 super( number, framesPerSec ); 058 } 059 060 /** 061 * Get the number of hours. 062 * @return The number of hours. 063 */ 064 public int getHours() 065 { 066 return (int)(this.getFrameNumber() / this.fps / 3600d); 067 } 068 069 /** 070 * Get the number of minutes within the hour. 071 * @return The number of minutes within the hour. 072 */ 073 public int getMinutes() 074 { 075 return (int)(this.getFrameNumber() / this.fps / 60d) % 60; 076 } 077 078 /** 079 * Get the number of seconds within the minute. 080 * @return The number of seconds within the minute. 081 */ 082 public int getSeconds() 083 { 084 return (int)(this.getFrameNumber() / this.fps) % 60; 085 } 086 087 /** 088 * Get the number of frames within the second. 089 * @return The number of frames within the second. 090 */ 091 public int getFrames() 092 { 093 return (int)(this.getFrameNumber() % this.fps); 094 } 095 096 /** 097 * {@inheritDoc} 098 * @see org.openimaj.video.timecode.FrameNumberVideoTimecode#toString() 099 */ 100 @Override 101 public String toString() 102 { 103 return this.getHours()+":"+this.getMinutes()+":"+this.getSeconds()+":" 104 +this.getFrames()+"/"+this.fps; 105 } 106 107 /** 108 * Parses a string (formatted as {@link #toString()}) back into a 109 * timecode object. 110 * 111 * @param s The string to parse 112 * @return A new {@link HrsMinSecFrameTimecode} or null if the string 113 * couldn't be parsed. 114 */ 115 public static HrsMinSecFrameTimecode fromString( final String s ) 116 { 117 final Pattern p = Pattern.compile( "(\\d+):(\\d+):(\\d+):(\\d+)/([\\d.]+)"); 118 final Matcher m = p.matcher( s ); 119 120 // Check for a match 121 if( !m.find() ) 122 return null; 123 124 // Extract all the bits and bobs 125 final double fps = Double.parseDouble(m.group(3)); 126 final int hrs = Integer.parseInt( m.group(0) ); 127 final int min = Integer.parseInt( m.group(1) ); 128 final int sec = Integer.parseInt( m.group(2) ); 129 final int frames = Integer.parseInt( m.group(3) ); 130 131 // Work out the frame number from the bits and bobs 132 final int frameNumber = (int)(frames + sec*fps + min*60*fps + hrs*3600*fps); 133 134 // Create a new object 135 final HrsMinSecFrameTimecode h = new HrsMinSecFrameTimecode( frameNumber, fps ); 136 return h; 137 } 138 139 /** 140 * {@inheritDoc} 141 * @see java.lang.Object#hashCode() 142 */ 143 @Override 144 public int hashCode() 145 { 146 return this.toString().hashCode(); 147 } 148 149 /** 150 * {@inheritDoc} 151 * @see java.lang.Object#equals(java.lang.Object) 152 */ 153 @Override 154 public boolean equals( final Object obj ) 155 { 156 if( obj instanceof HrsMinSecFrameTimecode ) 157 { 158 final HrsMinSecFrameTimecode h = (HrsMinSecFrameTimecode)obj; 159 return h.getHours() == this.getHours() && 160 h.getMinutes() == this.getMinutes() && 161 h.getSeconds() == this.getSeconds() && 162 h.getFrames() == this.getFrames(); 163 } 164 165 return false; 166 } 167 168 /** 169 * {@inheritDoc} 170 * @see org.openimaj.video.timecode.FrameNumberVideoTimecode#clone() 171 */ 172 @Override 173 public HrsMinSecFrameTimecode clone() 174 { 175 return new HrsMinSecFrameTimecode( this.getFrameNumber(), this.fps ); 176 } 177}