/// <summary> /// Given a new clip which either hasn't been seen or was processed incorrectly /// Direct its file to the AnalysisController for analysis /// Save the results in the database /// Return the results to the caller /// </summary> private async Task <IActionResult> ProcessNewClip(IFormFile file, string projectId, string clipId, string userId, string footagePath) { if (file is null) { return(StatusCode(StatusCodes.Status400BadRequest, new { message = $"Unable to find processed footage with id {projectId}/{clipId} for user {userId}\n" + "(did you mean to send a file?)" })); } HttpRequest currentRequest = HttpContext.Request; // initialize empty response AnalysisResult response = new AnalysisResult(); response.ClipId = clipId; response.FootagePath = footagePath; // process file in bg await Task.Run(() => { var fileStream = file.OpenReadStream(); // if an audio file was sent, return transcript if (file.ContentType.StartsWith("audio/")) { try { if (!(file.ContentType.EndsWith("/wav") || file.ContentType.EndsWith("/wave"))) { fileStream = ConversionController.ConvertToWav(fileStream, file.ContentType); } //var buf = ((MemoryStream)fileStream).GetBuffer(); //var f = System.IO.File.Create(@"C:\data\audio\converted.wav", buf.Length); //f.Write(buf); } finally { // analyze converted audio // AnalysisController.TranscribeAudio(ref response, file); AnalysisController.AnalyzeAudio(ref response, fileStream); fileStream.Close(); } } else if (file.ContentType.StartsWith("video/")) { try { var vidPt = Path.GetTempFileName(); var preAudPt = Path.GetTempFileName(); //@"C:\data\pre_tmp.wav"; var postAudPt = Path.GetTempFileName(); //@"C:\data\tmp.wav"; ConversionController.WriteStreamToDisk(fileStream, vidPt); fileStream = System.IO.File.OpenRead(vidPt); var splitStreams = ConversionController.SeparateAudioVideo(fileStream, file.ContentType); fileStream = splitStreams.audioStream; ConversionController.WriteStreamToDisk(fileStream, preAudPt); fileStream = ConversionController.ConvertToWavFiles(preAudPt, ""); ConversionController.WriteStreamToDisk(fileStream, postAudPt); fileStream = System.IO.File.OpenRead(postAudPt); } finally { AnalysisController.AnalyzeAudio(ref response, fileStream); fileStream.Close(); } } }); // load or make corresponding clip var clip = FindClip(clipId); if (clip == null) { clip = new AdobeClip { ClipId = clipId, FootagePath = footagePath, AnalysisResultString = response.Serialize() }; _montageContext.AdobeClips.Add(clip); _montageContext.SaveChanges(); } // load or make corresponding project var project = FindProject(projectId); if (project == null) { project = new AdobeProject { ProjectId = projectId, UserId = userId }; _montageContext.AdobeProjects.Add(project); _montageContext.SaveChanges(); } // load or make corresponding clip assignment var assignment = FindAssignment(projectId, clipId); if (assignment == null) { assignment = new ClipAssignment { ProjectId = projectId, UserId = project.UserId, ClipId = clip.ClipId }; _montageContext.ClipAssignments.Add(assignment); _montageContext.SaveChanges(); } await _montageContext.SaveChangesAsync(); response.ClipId = clipId; response.FootagePath = footagePath; return(Ok(response)); }
public async Task <IActionResult> AnalyzeClip([FromForm] IFormFile file, [FromForm] string projectId, [FromForm] string clipId, [FromForm] string userId, [FromForm] string footagePath) { // clipId, projectId, and userId are required parameters if (clipId is null || projectId is null || userId is null) { StatusCode(StatusCodes.Status400BadRequest, new { message = $"clipId, projectId, and userId must all not be null!\n" + $"(userId:{userId}//project:{projectId}//clip:{clipId})" }); } // read from DB, get response if it exists var query = from p in _montageContext.AdobeProjects where (p.ProjectId.Equals(projectId)) join a in _montageContext.ClipAssignments on p.ProjectId equals a.ProjectId join c in _montageContext.AdobeClips .Where(c => c.ClipId.Equals(clipId)) .DefaultIfEmpty() on a.ClipId equals c.ClipId select c; // IF clip+project seen, collect from db if (query.Any()) { AdobeClip clip = query.FirstOrDefault(); AnalysisResult result = (AnalysisResult.DeserializeResponse(clip.AnalysisResultString)); // if the result in the db has an error, delete it and try again if (result is null || result.Error) { // delete result from db try { _montageContext.AdobeClips.Remove(clip); _montageContext.SaveChanges(); } catch (Exception e) { return(StatusCode(StatusCodes.Status500InternalServerError, new { message = $"(this shouldn't happen!) Unable to repair malformed clip (userId:{userId}//project:{projectId}//clip:{clipId})\n" + "Please try adding under another clipId\n" + $"Exception:\n{e}" })); } // re-add it return(await ProcessNewClip(file, projectId, clipId, userId, footagePath)); } else { // return read from db // footagePath with update if provided result.FootagePath = footagePath ?? result.FootagePath; clip.AnalysisResultString = result.Serialize(); try { _montageContext.Update(clip); await _montageContext.SaveChangesAsync(); } catch (Exception e) { // this REALLY should never happen return(StatusCode(StatusCodes.Status500InternalServerError, new { message = $"Unable to update clip with new footage path" + $"Exception:\n{e}" })); } return(Ok(result)); } }