private async Task <List <Media> > GetBoxPlaylist(Playlist playlist, CTDbContext _context)
        {
            try
            {
                var client = await _box.GetBoxClientAsync();

                /// Try to refresh the access token
                var folderInfo = await client.FoldersManager.GetInformationAsync(playlist.PlaylistIdentifier);

                playlist.JsonMetadata = JObject.FromObject(folderInfo);

                var items = (await client.FoldersManager.GetFolderItemsAsync(playlist.PlaylistIdentifier, 500)).Entries.OfType <BoxFile>();
                // Process only files with an mp4 extension.
                items = items.Where(i => i.Name.Substring(i.Name.LastIndexOf(".") + 1) == "mp4").ToList();
                List <Media> newMedia = new List <Media>();

                foreach (var item in items)
                {
                    var file = await client.FilesManager.GetInformationAsync(item.Id);

                    // Check if there is a valid file.Id, and for the same playlist the same media does not exist.
                    if (file.Id.Length > 0 &&
                        !await _context.Medias.Where(m => m.UniqueMediaIdentifier == file.Id &&
                                                     m.SourceType == playlist.SourceType &&
                                                     m.PlaylistId == playlist.Id).AnyAsync())
                    {
                        newMedia.Add(new Media
                        {
                            SourceType            = playlist.SourceType,
                            PlaylistId            = playlist.Id,
                            UniqueMediaIdentifier = file.Id,
                            JsonMetadata          = JObject.FromObject(file),
                            CreatedAt             = file.CreatedAt ?? DateTime.Now
                        });
                    }
                }
                newMedia.ForEach(m => m.Name = GetMediaName(m));
                await _context.Medias.AddRangeAsync(newMedia);

                await _context.SaveChangesAsync();

                return(newMedia);
            }
            catch (Box.V2.Exceptions.BoxSessionInvalidatedException e)
            {
                GetLogger().LogError(e, "Box Token Failure.");
                await _slack.PostErrorAsync(e, "Box Token Failure.");

                throw;
            }
        }
Esempio n. 2
0
        public async Task <Video> DownloadBoxVideo(Media media)
        {
            try
            {
                var guid    = Guid.NewGuid().ToString();
                var newPath = Path.Combine(Globals.appSettings.DATA_DIRECTORY, guid + ".mp4");
                var client  = await _box.GetBoxClientAsync();

                var stream = await client.FilesManager.DownloadAsync(media.UniqueMediaIdentifier);

                using (var fileStream = File.Create(newPath))
                {
                    stream.CopyTo(fileStream);
                }
                if (FileRecord.IsValidFile(newPath))
                {
                    Video video = new Video
                    {
                        Video1 = await FileRecord.GetNewFileRecordAsync(newPath, Path.GetExtension(newPath))
                    };
                    return(video);
                }
                else
                {
                    // Deleting media is fine if download failed as we can get it back from the youtube playlist.
                    GetLogger().LogError("DownloadBoxVideo failed. mediaId {0}, removing Media record", media.Id);
                    using (var context = CTDbContext.CreateDbContext())
                    {
                        context.Medias.Remove(media);
                        context.SaveChanges();
                    }
                    return(null);
                }
            }
            catch (Box.V2.Exceptions.BoxSessionInvalidatedException e)
            {
                GetLogger().LogError(e, "Box Token Failure.");
                await _slack.PostErrorAsync(e, "Box Token Failure.");

                throw;
            }
        }
Esempio n. 3
0
        private async Task <MSTResult> performRecognitionAsync(string logId, string filePath, SpeechTranslationConfig speechConfig, TimeSpan restartOffset,
                                                               string sourceLanguage, Dictionary <string, List <Caption> > captions, Dictionary <string, TimeSpan> startAfterMap)
        {
            using (var audioInput = WavHelper.OpenWavFile(filePath))
            {
                var      logOnce            = new HashSet <string>();
                var      stopRecognition    = new TaskCompletionSource <int>();
                bool     verboseLogging     = false;
                TimeSpan lastSuccessfulTime = TimeSpan.Zero;
                string   errorCode          = "";
                using (var recognizer = new TranslationRecognizer(speechConfig, audioInput))
                {
                    recognizer.Recognized += (s, e) =>
                    {
                        if (e.Result.Reason == ResultReason.TranslatedSpeech)
                        {
                            JObject jObject           = JObject.Parse(e.Result.Properties.GetProperty(PropertyId.SpeechServiceResponse_JsonResult));
                            var     wordLevelCaptions = jObject["Words"]
                                                        .ToObject <List <MSTWord> >()
                                                        .OrderBy(w => w.Offset)
                                                        .ToList();

                            if (e.Result.Text == "" && wordLevelCaptions.Count == 0)
                            {
                                if (verboseLogging)
                                {
                                    TimeSpan _offset = new TimeSpan(e.Result.OffsetInTicks);
                                    TimeSpan _end    = e.Result.Duration.Add(_offset);
                                    _logger.LogInformation($"{logId}: Empty String: Begin={_offset.Minutes}:{_offset.Seconds},{_offset.Milliseconds}, End={_end.Minutes}:{_end.Seconds},{_end.Milliseconds}");
                                }
                                return;
                            }

                            if (wordLevelCaptions.Any())
                            {
                                // TODO/TOREVIEW: Is this a bug fix or redefinition? Could this change in later versions of the SDK?
                                long offsetDifference = e.Result.OffsetInTicks - wordLevelCaptions.FirstOrDefault().Offset;

                                wordLevelCaptions.ForEach(w => w.Offset += offsetDifference);
                            }

                            var sentenceLevelCaptions = MSTWord.WordLevelTimingsToSentenceLevelTimings(e.Result.Text, wordLevelCaptions);

                            // Convert back to time in original untrimmed video.
                            // These timings are used to check if we should be adding any captions
                            // However they are then used direcly for sentence level translations
                            // but not for the word-level timings of the primary language
                            TimeSpan begin = (new TimeSpan(e.Result.OffsetInTicks)).Add(restartOffset);
                            TimeSpan end   = e.Result.Duration.Add(begin);

                            if (verboseLogging)
                            {
                                _logger.LogInformation($"{logId}: Begin={begin.Minutes}:{begin.Seconds},{begin.Milliseconds}", begin);
                                _logger.LogInformation($"{logId}: End={end.Minutes}:{end.Seconds},{end.Milliseconds}");
                            }
                            // TODO/TOREVIEW:
                            // ToCaptionEntitiesWithWordTiming vs ToCaptionEntitiesInterpolate
                            // Can this code be simplified to use a single function?
                            // Also: Caution - it is possible that word timing data from MS may depend on SDK version

                            var newCaptions = MSTWord.ToCaptionEntitiesWithWordTiming(captions[sourceLanguage].Count, restartOffset, sentenceLevelCaptions);

                            if (begin >= startAfterMap[sourceLanguage])
                            {
                                captions[sourceLanguage].AddRange(newCaptions);
                                if (logOnce.Add("AddingMain"))
                                {
                                    _logger.LogInformation($"{logId}: Adding Primary Language captions");
                                }
                            }
                            else
                            {
                                if (logOnce.Add("SkippingMain"))
                                {
                                    _logger.LogInformation($"{logId}: Skipping Main captions because {begin} < {startAfterMap[sourceLanguage]}");
                                }
                            }
                            foreach (var element in e.Result.Translations)
                            {
                                var language   = element.Key;
                                var startAfter = startAfterMap[language];
                                if (begin >= startAfter)
                                {
                                    // Translations dont have word level timing so
                                    // interpolate between start and end
                                    newCaptions = Caption.ToCaptionEntitiesInterpolate(captions[language].Count, begin, end, element.Value);
                                    captions[element.Key].AddRange(newCaptions);

                                    if (logOnce.Add($"AddingTranslated {language}"))
                                    {
                                        _logger.LogInformation($"{logId}: Adding translation ({language}) captions");
                                    }
                                }
                                else
                                {
                                    if (logOnce.Add($"SkippingTranslated {language}"))
                                    {
                                        _logger.LogInformation($"{logId}: Skipping ({language}) captions because {begin} < {startAfter}");
                                    }
                                }
                            }
                        }
                        else if (e.Result.Reason == ResultReason.NoMatch)
                        {
                            _logger.LogInformation($"{logId}: NOMATCH: Speech could not be recognized.");
                        }
                    };

                    recognizer.Canceled += (s, e) =>
                    {
                        errorCode = e.ErrorCode.ToString();
                        _logger.LogInformation($"{logId}: CANCELED: ErrorCode={e.ErrorCode} Reason={e.Reason}");

                        if (e.Reason == CancellationReason.Error)
                        {
                            _logger.LogError($"{logId}: CANCELED: ErrorCode={e.ErrorCode} Reason={e.Reason}");

                            if (e.ErrorCode == CancellationErrorCode.ServiceTimeout ||
                                e.ErrorCode == CancellationErrorCode.ServiceUnavailable ||
                                e.ErrorCode == CancellationErrorCode.ConnectionFailure)
                            {
                                TimeSpan lastTime = TimeSpan.Zero;
                                if (captions.Count != 0)
                                {
                                    var lastCaption = captions[sourceLanguage].OrderBy(c => c.End).TakeLast(1).ToList().First();
                                    lastTime = lastCaption.End;
                                }

                                _logger.LogInformation($"{logId}: Retrying, LastSuccessTime={lastTime}");
                                lastSuccessfulTime = lastTime;
                            }
                            else if (e.ErrorCode != CancellationErrorCode.NoError)
                            {
                                _logger.LogInformation($"{logId}: CANCELED: ErrorCode={e.ErrorCode} Reason={e.Reason}");
                                _slackLogger.PostErrorAsync(new Exception($"{logId}: Transcription Failure"),
                                                            "Transcription Failure").GetAwaiter().GetResult();
                            }
                        }

                        stopRecognition.TrySetResult(0);
                    };

                    recognizer.SessionStarted += (s, e) =>
                    {
                        _logger.LogInformation($"{logId}: Session started event.");
                    };

                    recognizer.SessionStopped += (s, e) =>
                    {
                        _logger.LogInformation($"{logId}: Session stopped event. Stopping recognition.");
                        stopRecognition.TrySetResult(0);
                    };

                    // Starts continuous recognition. Uses StopContinuousRecognitionAsync() to stop recognition.
                    await recognizer.StartContinuousRecognitionAsync().ConfigureAwait(false);

                    // Waits for completion.
                    // Use Task.WaitAny to keep the task rooted.
                    Task.WaitAny(new[] { stopRecognition.Task });

                    // Stops recognition.
                    await recognizer.StopContinuousRecognitionAsync().ConfigureAwait(false);

                    _logger.LogInformation($"{logId}: Returning {captions.Count} languages, ErrorCode = {errorCode}, LastSuccessTime = {lastSuccessfulTime}");

                    return(new MSTResult
                    {
                        Captions = captions,
                        ErrorCode = errorCode,
                        LastSuccessTime = lastSuccessfulTime
                    });
                }
            }
        }