Beispiel #1
0
        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}");
        }
Beispiel #2
0
        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");
            }
        }
Beispiel #3
0
        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();
            }
        }
Beispiel #4
0
        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));
        }
Beispiel #5
0
 public async Task <ActionResult <IEnumerable <Caption> > > GetCaptions(string TranscriptionId)
 {
     return(await _captionQueries.GetCaptionsAsync(TranscriptionId));
 }
Beispiel #6
0
        /// <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;
                }
            }
        }