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 --> 01:19.000 093 * Keyword1, Keyword2 094 * 095 * 01:24.000 --> 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 --> 01:19.000 106 * Keyword1 107 * 108 * 00:44.000 --> 01:19.000 109 * Keyword2 110 * 111 * 01:24.000 --> 05:00.000 112 * Keyword1 113 * 114 * 01:24.000 --> 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}