001/**
002 * Copyright 2015 Tampere University of Technology, Pori Department
003 * 
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * 
008 *   http://www.apache.org/licenses/LICENSE-2.0
009 * 
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package service.tut.pori.subtitles;
017
018import java.util.Arrays;
019
020import org.apache.log4j.Logger;
021
022import service.tut.pori.contentanalysis.video.VideoDAO;
023import service.tut.pori.contentanalysis.video.VideoList;
024import core.tut.pori.context.ServiceInitializer;
025import core.tut.pori.http.StringResponse.StringData;
026import core.tut.pori.http.parameters.DataGroups;
027import core.tut.pori.users.UserIdentity;
028
029
030/**
031 * Subtitle service core methods.
032 * 
033 */
034public final class SubtitlesCore {
035  private static final DataGroups DATA_GROUP_TIMECODES = new DataGroups(service.tut.pori.contentanalysis.Definitions.DATA_GROUP_TIMECODES);
036  private static final Logger LOGGER = Logger.getLogger(SubtitlesCore.class);
037  
038  /**
039   * Subtitle file format
040   * 
041   */
042  public enum FileFormat {
043    /**  
044     * File format for WebVTT
045     * 
046     * <a href="http://dev.w3.org/html5/webvtt">WebVTT: The Web Video Text Tracks Format</a> 
047     */
048    WEBVTT;
049    
050    /**
051     * 
052     * @param value
053     * @return the value converted to file format
054     * @throws IllegalArgumentException on bad value
055     */
056    public static FileFormat fromFormatString(String value) throws IllegalArgumentException {
057      if(value != null){
058        switch(value.toUpperCase()){
059          case Definitions.FILE_FORMAT_WEBVTT:
060            return WEBVTT;
061          default:
062            break;
063        }
064      }
065      throw new IllegalArgumentException("Bad value : "+value);
066    }
067    
068    /**
069     * 
070     * @return this format as a string
071     */
072    public String toFormatString(){
073      switch(this){
074        case WEBVTT:
075          return Definitions.FILE_FORMAT_WEBVTT;
076        default:
077          throw new UnsupportedOperationException("Unhandeled "+FileFormat.class.toString()+" : "+name());
078      }
079    }
080  } // enum FileFormat
081  
082  /**
083   * Formatting option for media objects in a subtitle
084   * 
085   */
086  public enum SubtitleFormat {
087    /** 
088     * media objects will appear grouped by timecodes, combined in a single line 
089     * 
090     * An example in <a href="http://dev.w3.org/html5/webvtt">WEBVTT</a> format:
091     * <pre>
092     * 00:44.000 --&gt; 01:19.000
093     * Keyword1, Keyword2
094     *
095     * 01:24.000 --&gt; 05:00.000
096     * Keyword1, Keyword3
097     * </pre>
098     */
099    GROUPED,
100    /** 
101     * media objects will appear in individual lines, with one timecode sequence per media object 
102     * 
103     * An example in <a href="http://dev.w3.org/html5/webvtt">WEBVTT</a> format:
104     * <pre>
105     * 00:44.000 --&gt; 01:19.000
106     * Keyword1
107     *
108     * 00:44.000 --&gt; 01:19.000
109     * Keyword2
110     *
111     * 01:24.000 --&gt; 05:00.000
112     * Keyword1
113     * 
114     * 01:24.000 --&gt; 05:00.000
115     * Keyword3
116     * </pre>
117     */
118    INDIVIDUAL;
119    
120    /**
121     * 
122     * @param value
123     * @return value converted to SubtitleFormat
124     * @throws IllegalArgumentException on bad value
125     */
126    public static SubtitleFormat fromFormatString(String value) throws IllegalArgumentException {
127      if(value != null){
128        switch(value.toUpperCase()){
129          case Definitions.SUBTITLE_FORMAT_GROUPED:
130            return GROUPED;
131          case Definitions.SUBTITLE_FORMAT_INDIVIDUAL:
132            return INDIVIDUAL;
133          default:
134            break;
135        }
136      }
137      throw new IllegalArgumentException("Bad value: "+value);
138    }
139    
140    /**
141     * 
142     * @return the formatting option as a string
143     */
144    public String toFormatString() {
145      switch(this){
146        case GROUPED:
147          return Definitions.SUBTITLE_FORMAT_GROUPED;
148        case INDIVIDUAL:
149          return Definitions.SUBTITLE_FORMAT_INDIVIDUAL;
150        default:
151          throw new UnsupportedOperationException("Unhandeled "+SubtitleFormat.class.toString()+" : "+name());
152      }
153    }
154  } // enum SubtitleFormat
155  
156  /**
157   * 
158   */
159  private SubtitlesCore(){
160    // nothing needed
161  }
162
163  /**
164   * 
165   * @param authenticatedUser
166   * @param guid video GUID
167   * @param fileFormat
168   * @param subtitleFormat
169   * @param userIdFilter optional user id filter
170   * @return the formatted subtitle track or null on failure
171   * @throws IllegalArgumentException on bad values
172   */
173  public static StringData generateSubtitles(UserIdentity authenticatedUser, String guid, FileFormat fileFormat, SubtitleFormat subtitleFormat, long[] userIdFilter) throws IllegalArgumentException {
174    StringData data = null;
175    switch(fileFormat){
176      case WEBVTT:
177        if(subtitleFormat != SubtitleFormat.INDIVIDUAL){
178          throw new IllegalArgumentException("Unsupported subtitle format : "+subtitleFormat.toFormatString()+" for file format : "+fileFormat.toFormatString());
179        }
180        VideoList videos = ServiceInitializer.getDAOHandler().getSolrDAO(VideoDAO.class).search(authenticatedUser, DATA_GROUP_TIMECODES, Arrays.asList(guid), null, null, null, userIdFilter);
181        if(VideoList.isEmpty(videos)){
182          LOGGER.warn("Video not found or permission denied, GUID: "+guid);
183        }else{
184          WebVTTSubtitle vsub = new WebVTTSubtitle();
185          vsub.setSubtitleFormat(subtitleFormat);
186          vsub.setMediaObjects(videos.getVideos().get(0).getMediaObjects());
187          data = vsub;
188        }
189        break;
190      default:
191        throw new UnsupportedOperationException("Unhandeled "+FileFormat.class.toString()+" : "+fileFormat.name());
192    }
193    
194    return data;
195  }
196}