protected async override Task OnConsume(string example, TaskParameters taskParameters, ClientActiveTasks cleanup) { registerTask(cleanup, "ExampleTask"); // may throw AlreadyInProgress exception _logger.LogInformation("Example Task Starting"); int captionCount = 0; int transcriptionCount = 0; using (var _context = CTDbContext.CreateDbContext()) { CaptionQueries captionQueries = new CaptionQueries(_context); var transcriptions = await _context.Transcriptions.Take(30).ToListAsync(); foreach (var transcription in transcriptions) { var transcriptionId = transcription.Id; var videoID = transcription.VideoId; var captions = await captionQueries.GetCaptionsAsync(transcriptionId); _logger.LogInformation($"{transcription.Id}: Caption count= {captions.Count}"); transcriptionCount++; } } _logger.LogInformation($"Example Task Done. transcriptionCount={transcriptionCount} captionCount={captionCount}"); }
protected async override Task OnConsume(string transcriptionId, TaskParameters taskParameters, ClientActiveTasks cleanup) { registerTask(cleanup, transcriptionId); // may throw AlreadyInProgress exception GetLogger().LogInformation($"Creating VTT & SRT files for ({transcriptionId})"); using (var _context = CTDbContext.CreateDbContext()) { var transcription = await _context.Transcriptions.FindAsync(transcriptionId); CaptionQueries captionQueries = new CaptionQueries(_context); var captions = await captionQueries.GetCaptionsAsync(transcription.Id); var vttfile = await FileRecord.GetNewFileRecordAsync(Caption.GenerateWebVTTFile(captions, transcription.Language), ".vtt"); FileRecord?existingVtt = await _context.FileRecords.FindAsync(transcription.FileId); if (existingVtt is null) { GetLogger().LogInformation($"{transcriptionId}: Creating new vtt file {vttfile.FileName}"); await _context.FileRecords.AddAsync(vttfile); transcription.File = vttfile; _context.Entry(transcription).State = EntityState.Modified; } else { GetLogger().LogInformation($"{transcriptionId}: replacing existing vtt file contents {existingVtt.FileName}"); existingVtt.ReplaceWith(vttfile); _context.Entry(existingVtt).State = EntityState.Modified; } var srtfile = await FileRecord.GetNewFileRecordAsync(Caption.GenerateSrtFile(captions), ".srt"); FileRecord?existingSrt = await _context.FileRecords.FindAsync(transcription.SrtFileId); if (existingSrt is null) { GetLogger().LogInformation($"{transcriptionId}: Creating new srt file {srtfile.FileName}"); await _context.FileRecords.AddAsync(srtfile); transcription.SrtFile = srtfile; _context.Entry(transcription).State = EntityState.Modified; } else { GetLogger().LogInformation($"{transcriptionId}: replacing existing srt file contents {existingSrt.FileName}"); existingSrt.ReplaceWith(srtfile); _context.Entry(existingSrt).State = EntityState.Modified; } await _context.SaveChangesAsync(); GetLogger().LogInformation($"{transcriptionId}: Database updated"); } }
protected async override Task OnConsume(string transcriptionId, TaskParameters taskParameters, ClientActiveTasks cleanup) { registerTask(cleanup, transcriptionId); // may throw AlreadyInProgress exception using (var _context = CTDbContext.CreateDbContext()) { var transcription = await _context.Transcriptions.FindAsync(transcriptionId); FileRecord existingVtt = await _context.FileRecords.FindAsync(transcription.FileId); FileRecord existingSrt = await _context.FileRecords.FindAsync(transcription.SrtFileId); CaptionQueries captionQueries = new CaptionQueries(_context); var captions = await captionQueries.GetCaptionsAsync(transcription.Id); var vttfile = await FileRecord.GetNewFileRecordAsync(Caption.GenerateWebVTTFile(captions, transcription.Language), ".vtt"); if (string.IsNullOrEmpty(transcription.FileId)) { await _context.FileRecords.AddAsync(vttfile); transcription.File = vttfile; _context.Entry(transcription).State = EntityState.Modified; } else { existingVtt.ReplaceWith(vttfile); _context.Entry(existingVtt).State = EntityState.Modified; } var srtfile = await FileRecord.GetNewFileRecordAsync(Caption.GenerateSrtFile(captions), ".srt"); if (string.IsNullOrEmpty(transcription.SrtFileId)) { await _context.FileRecords.AddAsync(srtfile); transcription.SrtFile = srtfile; _context.Entry(transcription).State = EntityState.Modified; } else { existingSrt.ReplaceWith(srtfile); _context.Entry(existingSrt).State = EntityState.Modified; } await _context.SaveChangesAsync(); } }
public async Task <ActionResult <List <EPubSceneData> > > GetEpubData(string mediaId, string language) { var media = _context.Medias.Find(mediaId); Video video = await _context.Videos.FindAsync(media.VideoId); if (video.SceneData == null) { return(NotFound()); } EPub epub = new EPub { Language = language, SourceType = ResourceType.Media, SourceId = mediaId }; var captions = await _captionQueries.GetCaptionsAsync(media.VideoId, epub.Language); return(GetSceneData(video.SceneData["Scenes"] as JArray, captions)); }
public async Task <ActionResult <IEnumerable <Caption> > > GetCaptions(string TranscriptionId) { return(await _captionQueries.GetCaptionsAsync(TranscriptionId)); }
/// <summary> /// [2020.7.7] For the purpose of resuming failed transcriptions, all the captions of the failed transcription would now be stored in the database. /// Before resuming, all the old captions would be queried out from the database and stored in a dictionary, which will be passed to the /// transcription function along with the resume time point. /// </summary> /// <param name="videoId"></param> /// <param name="taskParameters"></param> /// <returns></returns> protected async override Task OnConsume(string videoId, TaskParameters taskParameters, ClientActiveTasks cleanup) { registerTask(cleanup, videoId); // may throw AlreadyInProgress exception if (Globals.appSettings.MOCK_RECOGNITION == "MOCK") { buildMockCaptions(videoId); } using (var _context = CTDbContext.CreateDbContext()) { // TODO: taskParameters.Force should wipe all captions and reset the Transcription Status Video video = await _context.Videos.Include(v => v.Video1).Where(v => v.Id == videoId).FirstAsync(); // ! Note the 'Include' ; we don't build the whole tree of related Entities if (video.TranscriptionStatus == Video.TranscriptionStatusMessages.NOERROR) { GetLogger().LogInformation($"{videoId}:Skipping Transcribing of- already complete"); return; } // GetKey can throw if the video.Id is currently being transcribed // However registerTask should have already detected that Key key = TaskEngineGlobals.KeyProvider.GetKey(video.Id); video.TranscribingAttempts += 10; await _context.SaveChangesAsync(); try { // create Dictionary and pass it to the recognition function var captionsMap = new Dictionary <string, List <Caption> >(); // Set Source Language and Target (translation) Languages var sourceLanguage = String.IsNullOrWhiteSpace(Globals.appSettings.SPEECH_RECOGNITION_DIALECT) ? Languages.ENGLISH_AMERICAN : Globals.appSettings.SPEECH_RECOGNITION_DIALECT.Trim(); var translations = new List <string> { Languages.ENGLISH_AMERICAN, Languages.SIMPLIFIED_CHINESE, Languages.KOREAN, Languages.SPANISH, Languages.FRENCH }; if (!String.IsNullOrWhiteSpace(Globals.appSettings.LANGUAGE_TRANSLATIONS)) { translations = Globals.appSettings.LANGUAGE_TRANSLATIONS.Split(',').ToList(); } GetLogger().LogInformation($"{videoId}: ({sourceLanguage}). Translation(s) = ({String.Join(',', translations)})"); // Different languages may not be as complete // So find the minimum timespan of the max observed ending for each language TimeSpan shortestTime = TimeSpan.MaxValue; // Cant use TimeSpan.Zero to mean unset var startAfterMap = new Dictionary <string, TimeSpan>(); var allLanguages = new List <string>(translations); allLanguages.Add(sourceLanguage); foreach (string language in allLanguages) { var existing = await _captionQueries.GetCaptionsAsync(video.Id, language); captionsMap[language] = existing; startAfterMap[language] = TimeSpan.Zero; if (existing.Any()) { TimeSpan lastCaptionTime = existing.Select(c => c.End).Max(); startAfterMap[language] = lastCaptionTime; GetLogger().LogInformation($"{ videoId}:{language}. Last Caption at {lastCaptionTime}"); } } //var lastSuccessTime = shortestTime < TimeSpan.MaxValue ? shortestTime : TimeSpan.Zero; //if (video.JsonMetadata != null && video.JsonMetadata["LastSuccessfulTime"] != null) //{ // lastSuccessTime = TimeSpan.Parse(video.JsonMetadata["LastSuccessfulTime"].ToString()); //} var result = await _msTranscriptionService.RecognitionWithVideoStreamAsync(videoId, video.Video1, key, captionsMap, sourceLanguage, startAfterMap); if (video.JsonMetadata == null) { video.JsonMetadata = new JObject(); } TaskEngineGlobals.KeyProvider.ReleaseKey(key, video.Id); foreach (var captionsInLanguage in result.Captions) { var theLanguage = captionsInLanguage.Key; var theCaptions = captionsInLanguage.Value; if (theCaptions.Any()) { var t = _context.Transcriptions.SingleOrDefault(t => t.VideoId == video.Id && t.Language == theLanguage); GetLogger().LogInformation($"Find Existing Transcriptions null={t == null}"); // Did we get the default or an existing Transcription entity? if (t == null) { t = new Transcription() { Captions = theCaptions, Language = theLanguage, VideoId = video.Id }; _context.Add(t); } else { // Transcriptions already existed, we are just completing them, so add only the new ones // TODO/TOREVIEW: Does this filter actually help, if existing caption entries were edited by hand? var newCaptions = theCaptions.Where(c => c.Id == null); t.Captions.AddRange(newCaptions); } } } video.TranscriptionStatus = result.ErrorCode; video.JsonMetadata["LastSuccessfulTime"] = result.LastSuccessTime.ToString(); await _context.SaveChangesAsync(); _sceneDetectionTask.Publish(video.Id); video.Transcriptions.ForEach(t => _generateVTTFileTask.Publish(t.Id)); } catch (Exception ex) { GetLogger().LogError(ex, $"{videoId}: Transcription Exception:${ex.StackTrace}"); video.TranscribingAttempts += 1000; await _context.SaveChangesAsync(); throw; } } }