/// <summary> /// Builds the current clips stored into a single stream, then removes the clips. /// </summary> /// <param name="sessionUid">UID of the session to proces</param> /// <returns></returns> public async Task <bool> FinishClipAsync(string userUid, DomainModels.BlobUpload upload) { var session = await DbContext.Sessions.Include(x => x.Clips).ThenInclude(x => x.Media) .Include(x => x.Podcast).FirstOrDefaultAsync(x => x.UID == upload.SessionUid); if (session == null) { return(false); } using (var stream = upload.Data.OpenReadStream()) { var url = await MediaStorage.UploadStreamAsync(userUid, upload.SessionUid, upload.ClipUid, stream); var clip = session.Clips.FirstOrDefault(c => c.UID == upload.ClipUid); if (clip == null) { var id = CreateClip(url, session.ID, upload.ClipUid, upload.Name); clip = await DbContext.Clips.FindAsync(id); } var media = new Db.Media { ClipID = clip.ID, MediaUrl = url, UserUID = userUid, UID = Guid.NewGuid() }; DbContext.Media.Add(media); var mediaList = new List <Stream>(); foreach (var entry in clip.Media) { mediaList.Add(await StreamBuilder.GetStreamFromUrlAsync(entry.MediaUrl)); } if (mediaList.Count() > 1) { var concatStream = Audio.AudioConcatUtils.ConcatAudioStreams(mediaList); var concatUrl = await MediaStorage.UploadStreamAsync("concat", upload.SessionUid, upload.ClipUid, stream); clip.MediaUrl = concatUrl; } } await DbContext.SaveChangesAsync(); return(true); }
/// <summary> /// Updates the stream belonging to the edit. /// </summary> /// <param name="edit">Edit to update.</param> /// <returns></returns> private async Task UpdateStreamAsync(Guid sessionUid, int editId) { var edit = await DbContext.Edits.Include(c => c.Clip).ThenInclude(c => c.Media).ThenInclude(c => c.Stream).FirstOrDefaultAsync(c => c.ID == editId); foreach (var entry in edit.Clip.Media) { var stream = await StreamBuilder.GetStreamFromUrlAsync(entry.MediaUrl); var file = await Audio.AudioEditUtils.TrimFile(stream, edit.StartTrim, edit.EndTrim); await MediaStorage.UploadStreamAsync(entry.UserUID, sessionUid, entry.Clip.UID, file); } await DbContext.SaveChangesAsync(); }
/// <summary> /// Compiles the edit files into one streamable file and sends it to the publisher. /// </summary> /// <param name="sessionUid">UID of the session.</param> /// <param name="userUid">User requesting the action.</param> /// <returns></returns> public async Task <bool> FinishEditingAsync(Guid sessionUid, string userUid) { var session = await DbContext.Sessions.Include(c => c.Podcast).Include(c => c.TimelineEntries).ThenInclude(c => c.Clip) .ThenInclude(c => c.Media) .FirstOrDefaultAsync(x => x.UID == sessionUid && x.Podcast.Members.Any(c => c.UserUID == userUid && c.IsAdmin)); if (session == null) { return(false); } session.IsFinishedEditing = true; await DbContext.SaveChangesAsync(); var combinedStreams = new List <string>(); foreach (var entry in session.TimelineEntries.OrderBy(c => c.Position)) { var streams = new List <System.IO.Stream>(); foreach (var stream in entry.Clip.Media) { streams.Add(await StreamBuilder.GetStreamFromUrlAsync(stream.MediaUrl)); } var combinedStream = Audio.AudioConcatUtils.ConcatAudioStreams(streams); var url = await MediaStorage.UploadStreamAsync(Guid.NewGuid().ToString(), sessionUid, Guid.NewGuid(), combinedStream); combinedStreams.Add(url); } await TimelineBus.SendAsync(new Vocalia.ServiceBus.Types.Publishing.Timeline { PodcastUID = session.Podcast.UID, Date = session.Date, UID = session.UID, TimelineEntries = combinedStreams }); return(true); }
/// <summary> /// Creates a new episode from the stored unassigned episode. /// </summary> /// <param name="userUid">UserUID of the current user.</param> /// <param name="episode">Episode to create.</param> /// <returns></returns> private async Task <Db.Episode> CreateNewEpisode(string userUid, DomainModels.Episode episode) { var dbPodcast = await DbContext.Podcasts.FirstOrDefaultAsync(c => c.UID == episode.PodcastUID && c.Members.Any(x => x.UserUID == userUid)); var dbUnassignedEpisode = await DbContext.UnassignedEpisodes.Include(c => c.Clips).FirstOrDefaultAsync(c => c.UID == episode.UID); if (dbUnassignedEpisode == null) { return(null); } var clipStreams = new List <Stream>(); foreach (var clip in dbUnassignedEpisode.Clips) { clipStreams.Add(await StreamBuilder.GetStreamFromUrlAsync(clip.MediaUrl)); } var compiledStream = Audio.AudioConcatUtils.SequenceAudioStreams(clipStreams); var url = await MediaStorage.UploadStreamAsync("rss", dbPodcast.UID, Guid.NewGuid(), compiledStream); var dbEpisode = new Db.Episode { UID = Guid.NewGuid(), Title = episode.Title, Description = episode.Description, RssUrl = string.Concat(Config["RssPath"], dbPodcast.UID, "/", episode.UID), MediaUrl = url, PublishDate = DateTime.Now, PodcastID = dbPodcast.ID }; DbContext.Episodes.Add(dbEpisode); dbUnassignedEpisode.IsCompleted = true; await DbContext.SaveChangesAsync(); return(dbEpisode); }