public static int AddTask(Microsoft.Azure.WebJobs.ExecutionContext execContext, CloudMediaContext context, IJob job, IAsset sourceAsset, string value, string processor, string presetfilename, string stringtoreplace, ref int taskindex, int priority = 10, string specifiedStorageAccountName = null)
        {
            if (value != null)
            {
                // Get a media processor reference, and pass to it the name of the
                // processor to use for the specific task.
                IMediaProcessor mediaProcessor = MediaServicesHelper.GetLatestMediaProcessorByName(context, processor);

                string presetPath = Path.Combine(System.IO.Directory.GetParent(execContext.FunctionDirectory).FullName, "presets", presetfilename);

                string Configuration = File.ReadAllText(presetPath).Replace(stringtoreplace, value);

                // Create a task with the encoding details, using a string preset.
                var task = job.Tasks.AddNew(processor + " task",
                                            mediaProcessor,
                                            Configuration,
                                            TaskOptions.None);

                task.Priority = priority;

                // Specify the input asset to be indexed.
                task.InputAssets.Add(sourceAsset);

                // Add an output asset to contain the results of the job.
                // Use a non default storage account in case this was provided in 'AddTask'

                task.OutputAssets.AddNew(sourceAsset.Name + " " + processor + " Output", specifiedStorageAccountName, AssetCreationOptions.None);

                return(taskindex++);
            }
            else
            {
                return(-1);
            }
        }
示例#2
0
        public static IContentKey MakeContentKey(CloudMediaContext context, ContentKeyType contentKeyType, string contentKeyId = null, string contentKeySecret = null)
        {
            string contentKeyName;

            switch (contentKeyType)
            {
            case ContentKeyType.CommonEncryption:
                contentKeyName = "Common Encryption ContentKey";
                return(MediaServicesHelper.CreateContentKey(context, contentKeyName, ContentKeyType.CommonEncryption, contentKeyId, contentKeySecret));

            case ContentKeyType.CommonEncryptionCbcs:
                contentKeyName = "Common Encryption CBCS ContentKey";
                return(MediaServicesHelper.CreateContentKey(context, contentKeyName, ContentKeyType.CommonEncryptionCbcs, contentKeyId, contentKeySecret));

            case ContentKeyType.EnvelopeEncryption:
                contentKeyName = "Envelope Encryption ContentKey";
                return(MediaServicesHelper.CreateContentKey(context, contentKeyName, ContentKeyType.EnvelopeEncryption, contentKeyId, contentKeySecret));
            }

            throw new NotImplementedException(contentKeyType.ToString() + " is not supported");
        }
        public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log)
        {
            log.Info($"Webhook was triggered!");

            string jsonContent = await req.Content.ReadAsStringAsync();

            dynamic data = JsonConvert.DeserializeObject(jsonContent);

            log.Info(jsonContent);

            if (data.ruCount == null && data.ruSpeed == null)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new
                {
                    error = "Please pass ruCount and ruSpeed in the input object"
                }));
            }


            int              targetNbRU = -1;
            int?             nbunits    = null;
            bool             relative   = false;
            string           RUspeed    = "";
            ReservedUnitType?type       = null;

            if (data.ruSpeed != null)
            {
                RUspeed = ((string)data.ruSpeed).ToUpper();
                if (RUspeed == "S1")
                {
                    type = ReservedUnitType.Basic;
                }
                else if (RUspeed == "S2")
                {
                    type = ReservedUnitType.Standard;
                }
                else if (RUspeed == "S3")
                {
                    type = ReservedUnitType.Premium;
                }
                else
                {
                    return(req.CreateResponse(HttpStatusCode.BadRequest, new
                    {
                        error = "Error parsing ruSpeed"
                    }));
                }
            }

            if (data.ruCount != null)
            {
                string RUcount = (string)data.ruCount;
                if (RUcount[0] == '+' || RUcount[0] == '-')
                {
                    relative = true;
                    try
                    {
                        nbunits = int.Parse(RUcount);
                    }
                    catch
                    {
                        return(req.CreateResponse(HttpStatusCode.BadRequest, new
                        {
                            error = "Error (1) parsing ruCount"
                        }));
                    }
                }
                else
                {
                    try
                    {
                        nbunits = int.Parse(RUcount);
                    }
                    catch
                    {
                        return(req.CreateResponse(HttpStatusCode.BadRequest, new
                        {
                            error = "Error (2) parsing ruCount"
                        }));
                    }
                }
            }

            MediaServicesCredentials amsCredentials = new MediaServicesCredentials();

            log.Info($"Using Azure Media Service Rest API Endpoint : {amsCredentials.AmsRestApiEndpoint}");

            try
            {
                AzureAdTokenCredentials tokenCredentials = new AzureAdTokenCredentials(amsCredentials.AmsAadTenantDomain,
                                                                                       new AzureAdClientSymmetricKey(amsCredentials.AmsClientId, amsCredentials.AmsClientSecret),
                                                                                       AzureEnvironments.AzureCloudEnvironment);

                AzureAdTokenProvider tokenProvider = new AzureAdTokenProvider(tokenCredentials);

                _context = new CloudMediaContext(amsCredentials.AmsRestApiEndpoint, tokenProvider);
            }
            catch (Exception ex)
            {
                string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : "");
                log.Info($"ERROR: Exception {message}");
                return(req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message }));
            }

            IEncodingReservedUnit EncResUnit = _context.EncodingReservedUnits.FirstOrDefault();

            targetNbRU = EncResUnit.CurrentReservedUnits;
            ReservedUnitType targetType = EncResUnit.ReservedUnitType;

            log.Info("Current type of media RU: " + MediaServicesHelper.ReturnNewRUName(EncResUnit.ReservedUnitType));
            log.Info("Current count of media RU: " + EncResUnit.CurrentReservedUnits);
            log.Info("Maximum reservable media RUs: " + EncResUnit.MaxReservableUnits);

            if (nbunits != null)
            {
                if (relative)
                {
                    if (((int)nbunits) > 0)
                    {
                        log.Info($"Adding {nbunits} unit(s)");
                    }
                    else
                    {
                        log.Info($"Removing {nbunits} unit(s)");
                    }
                    targetNbRU = Math.Max(targetNbRU + (int)nbunits, 0);
                }
                else
                {
                    log.Info($"Changing to {nbunits} unit(s)");
                    targetNbRU = (int)nbunits;
                }
            }

            if (type != null)
            {
                string sru = MediaServicesHelper.ReturnNewRUName((ReservedUnitType)type);
                log.Info($"Changing to {sru} speed");
                targetType = (ReservedUnitType)type;
            }

            if (targetNbRU == 0 && targetType != ReservedUnitType.Basic)
            {
                targetType = ReservedUnitType.Basic; // 0 units so we switch to S1
            }

            bool Error = false;

            try
            {
                EncResUnit.CurrentReservedUnits = targetNbRU;
                EncResUnit.ReservedUnitType     = targetType;
                EncResUnit.Update();
                EncResUnit = _context.EncodingReservedUnits.FirstOrDefault(); // Refresh
            }
            catch (Exception ex)
            {
                Error = true;
            }

            log.Info("Media RU unit(s) updated successfully.");
            log.Info("New current speed of media RU  : " + MediaServicesHelper.ReturnNewRUName(EncResUnit.ReservedUnitType));
            log.Info("New current count of media RU : " + EncResUnit.CurrentReservedUnits);

            return(req.CreateResponse(HttpStatusCode.OK, new
            {
                success = (!Error).ToString(),
                maxRu = EncResUnit.MaxReservableUnits,
                newRuCount = EncResUnit.CurrentReservedUnits,
                newRuSpeed = MediaServicesHelper.ReturnNewRUName(EncResUnit.ReservedUnitType)
            }));
        }
示例#4
0
        public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log, Microsoft.Azure.WebJobs.ExecutionContext execContext)
        {
            // Variables
            int taskindex               = 0;
            int OutputMES               = -1;
            int OutputPremium           = -1;
            int OutputIndex1            = -1;
            int OutputIndex2            = -1;
            int OutputOCR               = -1;
            int OutputFaceDetection     = -1;
            int OutputFaceRedaction     = -1;
            int OutputMotion            = -1;
            int OutputSummarization     = -1;
            int OutputHyperlapse        = -1;
            int OutputMesThumbnails     = -1;
            int OutputVideoAnnotation   = -1;
            int OutputContentModeration = -1;

            int    id               = 0;
            string programid        = "";
            string programName      = "";
            string channelName      = "";
            string programUrl       = "";
            string programState     = "";
            string lastProgramState = "";

            IJob  job             = null;
            ITask taskEncoding    = null;
            int   NumberJobsQueue = 0;

            int intervalsec = 60; // Interval for each subclip job (sec). Default is 60

            TimeSpan starttime = TimeSpan.FromSeconds(0);
            TimeSpan duration  = TimeSpan.FromSeconds(intervalsec);

            log.Info($"Webhook was triggered!");
            string triggerStart = DateTime.UtcNow.ToString("o");

            string jsonContent = await req.Content.ReadAsStringAsync();

            dynamic data = JsonConvert.DeserializeObject(jsonContent);

            log.Info(jsonContent);

            if (data.channelName == null || data.programName == null)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new
                {
                    error = "Please pass channel name and program name in the input object (channelName, programName)"
                }));
            }

            if (data.intervalSec != null)
            {
                intervalsec = (int)data.intervalSec;
            }

            MediaServicesCredentials amsCredentials = new MediaServicesCredentials();

            log.Info($"Using Azure Media Service Rest API Endpoint : {amsCredentials.AmsRestApiEndpoint}");

            try
            {
                AzureAdTokenCredentials tokenCredentials = new AzureAdTokenCredentials(amsCredentials.AmsAadTenantDomain,
                                                                                       new AzureAdClientSymmetricKey(amsCredentials.AmsClientId, amsCredentials.AmsClientSecret),
                                                                                       AzureEnvironments.AzureCloudEnvironment);

                AzureAdTokenProvider tokenProvider = new AzureAdTokenProvider(tokenCredentials);

                _context = new CloudMediaContext(amsCredentials.AmsRestApiEndpoint, tokenProvider);

                // find the Channel, Program and Asset
                channelName = (string)data.channelName;
                var channel = _context.Channels.Where(c => c.Name == channelName).FirstOrDefault();
                if (channel == null)
                {
                    log.Info("Channel not found");
                    return(req.CreateResponse(HttpStatusCode.BadRequest, new
                    {
                        error = "Channel not found"
                    }));
                }

                programName = (string)data.programName;
                var program = channel.Programs.Where(p => p.Name == programName).FirstOrDefault();
                if (program == null)
                {
                    log.Info("Program not found");
                    return(req.CreateResponse(HttpStatusCode.BadRequest, new
                    {
                        error = "Program not found"
                    }));
                }

                programState = program.State.ToString();
                programid    = program.Id;
                var asset = ManifestHelpers.GetAssetFromProgram(_context, programid);

                if (asset == null)
                {
                    log.Info($"Asset not found for program {programid}");
                    return(req.CreateResponse(HttpStatusCode.BadRequest, new
                    {
                        error = "Asset not found"
                    }));
                }

                log.Info($"Using asset Id : {asset.Id}");

                // Table storage to store and real the last timestamp processed
                // Retrieve the storage account from the connection string.
                CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials(amsCredentials.StorageAccountName, amsCredentials.StorageAccountKey), true);

                // Create the table client.
                CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

                // Retrieve a reference to the table.
                CloudTable table = tableClient.GetTableReference("liveanalytics");

                // Create the table if it doesn't exist.

                if (!table.CreateIfNotExists())
                {
                    log.Info($"Table {table.Name} already exists");
                }
                else
                {
                    log.Info($"Table {table.Name} created");
                }

                var lastendtimeInTable = ManifestHelpers.RetrieveLastEndTime(table, programid);

                // Get the manifest data (timestamps)
                var assetmanifestdata = ManifestHelpers.GetManifestTimingData(_context, asset, log);

                log.Info("Timestamps: " + string.Join(",", assetmanifestdata.TimestampList.Select(n => n.ToString()).ToArray()));

                var livetime = TimeSpan.FromSeconds((double)assetmanifestdata.TimestampEndLastChunk / (double)assetmanifestdata.TimeScale);

                log.Info($"Livetime: {livetime}");

                starttime = ManifestHelpers.ReturnTimeSpanOnGOP(assetmanifestdata, livetime.Subtract(TimeSpan.FromSeconds(intervalsec)));
                log.Info($"Value starttime : {starttime}");

                if (lastendtimeInTable != null)
                {
                    lastProgramState = lastendtimeInTable.ProgramState;
                    log.Info($"Value ProgramState retrieved : {lastProgramState}");

                    var lastendtimeInTableValue = TimeSpan.Parse(lastendtimeInTable.LastEndTime);
                    log.Info($"Value lastendtimeInTable retrieved : {lastendtimeInTableValue}");

                    id = int.Parse(lastendtimeInTable.Id);
                    log.Info($"Value id retrieved : {id}");

                    if (lastendtimeInTableValue != null)
                    {
                        var delta = (livetime - lastendtimeInTableValue - TimeSpan.FromSeconds(intervalsec)).Duration();
                        log.Info($"Delta: {delta}");

                        //if (delta < (new TimeSpan(0, 0, 3*intervalsec))) // less than 3 times the normal duration (3*60s)
                        if (delta < (TimeSpan.FromSeconds(3 * intervalsec))) // less than 3 times the normal duration (3*60s)
                        {
                            starttime = lastendtimeInTableValue;
                            log.Info($"Value new starttime : {starttime}");
                        }
                    }
                }

                duration = livetime - starttime;
                log.Info($"Value duration: {duration}");

                // D:\home\site\wwwroot\Presets\LiveSubclip.json
                string ConfigurationSubclip = File.ReadAllText(Path.Combine(System.IO.Directory.GetParent(execContext.FunctionDirectory).FullName, "presets", "LiveSubclip.json")).Replace("0:00:00.000000", starttime.Subtract(TimeSpan.FromMilliseconds(100)).ToString()).Replace("0:00:30.000000", duration.Add(TimeSpan.FromMilliseconds(200)).ToString());

                int priority = 10;
                if (data.priority != null)
                {
                    priority = (int)data.priority;
                }

                // MES Subclipping TASK
                // Declare a new encoding job with the Standard encoder
                job = _context.Jobs.Create("Azure Function - Job for Live Analytics - " + programName, priority);
                // Get a media processor reference, and pass to it the name of the
                // processor to use for the specific task.
                IMediaProcessor processor = MediaServicesHelper.GetLatestMediaProcessorByName(_context, "Media Encoder Standard");

                // Change or modify the custom preset JSON used here.
                // string preset = File.ReadAllText("D:\home\site\wwwroot\Presets\H264 Multiple Bitrate 720p.json");

                // Create a task with the encoding details, using a string preset.
                // In this case "H264 Multiple Bitrate 720p" system defined preset is used.
                taskEncoding = job.Tasks.AddNew("Subclipping task",
                                                processor,
                                                ConfigurationSubclip,
                                                TaskOptions.None);

                // Specify the input asset to be encoded.
                taskEncoding.InputAssets.Add(asset);
                OutputMES = taskindex++;

                // Add an output asset to contain the results of the job.
                // This output is specified as AssetCreationOptions.None, which
                // means the output asset is not encrypted.
                var subclipasset = taskEncoding.OutputAssets.AddNew(asset.Name + " subclipped " + triggerStart, JobHelpers.OutputStorageFromParam(data.mesSubclip), AssetCreationOptions.None);

                log.Info($"Adding media analytics tasks");

                /*
                 *      // Media Analytics
                 *      OutputIndex1 = JobHelpers.AddTask(job, subclipasset, (string)data.indexV1Language, "Azure Media Indexer", "IndexerV1.xml", "English", ref taskindex);
                 *      OutputIndex2 = JobHelpers.AddTask(job, subclipasset, (string)data.indexV2Language, "Azure Media Indexer 2 Preview", "IndexerV2.json", "EnUs", ref taskindex);
                 *      OutputOCR = JobHelpers.AddTask(job, subclipasset, (string)data.ocrLanguage, "Azure Media OCR", "OCR.json", "AutoDetect", ref taskindex);
                 *      OutputFaceDetection = JobHelpers.AddTask(job, subclipasset, (string)data.faceDetectionMode, "Azure Media Face Detector", "FaceDetection.json", "PerFaceEmotion", ref taskindex);
                 *      OutputFaceRedaction = JobHelpers.AddTask(job, subclipasset, (string)data.faceRedactionMode, "Azure Media Redactor", "FaceRedaction.json", "combined", ref taskindex, priority - 1);
                 *      OutputMotion = JobHelpers.AddTask(job, subclipasset, (string)data.motionDetectionLevel, "Azure Media Motion Detector", "MotionDetection.json", "medium", ref taskindex, priority - 1);
                 *      OutputSummarization = JobHelpers.AddTask(job, subclipasset, (string)data.summarizationDuration, "Azure Media Video Thumbnails", "Summarization.json", "0.0", ref taskindex);
                 *      OutputHyperlapse = JobHelpers.AddTask(job, subclipasset, (string)data.hyperlapseSpeed, "Azure Media Hyperlapse", "Hyperlapse.json", "8", ref taskindex);
                 *      OutputMesThumbnails = JobHelpers.AddTask(job, subclipasset, (string)data.mesThumbnailsStart, "Media Encoder Standard", "MesThumbnails.json", "{Best}", ref taskindex);
                 */

                //new
                OutputIndex1            = JobHelpers.AddTask(execContext, _context, job, subclipasset, (data.indexV1 == null) ? (string)data.indexV1Language : ((string)data.indexV1.language ?? "English"), "Azure Media Indexer", "IndexerV1.xml", "English", ref taskindex, specifiedStorageAccountName: JobHelpers.OutputStorageFromParam(data.indexV1));
                OutputIndex2            = JobHelpers.AddTask(execContext, _context, job, subclipasset, (data.indexV2 == null) ? (string)data.indexV2Language : ((string)data.indexV2.language ?? "EnUs"), "Azure Media Indexer 2 Preview", "IndexerV2.json", "EnUs", ref taskindex, specifiedStorageAccountName: JobHelpers.OutputStorageFromParam(data.indexV2));
                OutputOCR               = JobHelpers.AddTask(execContext, _context, job, subclipasset, (data.ocr == null) ? (string)data.ocrLanguage : ((string)data.ocr.language ?? "AutoDetect"), "Azure Media OCR", "OCR.json", "AutoDetect", ref taskindex, specifiedStorageAccountName: JobHelpers.OutputStorageFromParam(data.ocr));
                OutputFaceDetection     = JobHelpers.AddTask(execContext, _context, job, subclipasset, (data.faceDetection == null) ? (string)data.faceDetectionMode : ((string)data.faceDetection.mode ?? "PerFaceEmotion"), "Azure Media Face Detector", "FaceDetection.json", "PerFaceEmotion", ref taskindex, specifiedStorageAccountName: JobHelpers.OutputStorageFromParam(data.faceDetection));
                OutputFaceRedaction     = JobHelpers.AddTask(execContext, _context, job, subclipasset, (data.faceRedaction == null) ? (string)data.faceRedactionMode : ((string)data.faceRedaction.mode ?? "comined"), "Azure Media Redactor", "FaceRedaction.json", "combined", ref taskindex, priority - 1, specifiedStorageAccountName: JobHelpers.OutputStorageFromParam(data.faceRedaction));
                OutputMotion            = JobHelpers.AddTask(execContext, _context, job, subclipasset, (data.motionDetection == null) ? (string)data.motionDetectionLevel : ((string)data.motionDetection.level ?? "medium"), "Azure Media Motion Detector", "MotionDetection.json", "medium", ref taskindex, priority - 1, specifiedStorageAccountName: JobHelpers.OutputStorageFromParam(data.motionDetection));
                OutputSummarization     = JobHelpers.AddTask(execContext, _context, job, subclipasset, (data.summarization == null) ? (string)data.summarizationDuration : ((string)data.summarization.duration ?? "0.0"), "Azure Media Video Thumbnails", "Summarization.json", "0.0", ref taskindex, specifiedStorageAccountName: JobHelpers.OutputStorageFromParam(data.summarization));
                OutputVideoAnnotation   = JobHelpers.AddTask(execContext, _context, job, subclipasset, (data.videoAnnotation != null) ? "1.0" : null, "Azure Media Video Annotator", "VideoAnnotation.json", "1.0", ref taskindex, specifiedStorageAccountName: JobHelpers.OutputStorageFromParam(data.videoAnnotation));
                OutputContentModeration = JobHelpers.AddTask(execContext, _context, job, subclipasset, (data.contentModeration != null) ? "2.0" : null, "Azure Media Content Moderator", "ContentModeration.json", "2.0", ref taskindex, specifiedStorageAccountName: JobHelpers.OutputStorageFromParam(data.contentModeration));

                // MES Thumbnails
                OutputMesThumbnails = JobHelpers.AddTask(execContext, _context, job, subclipasset, (data.mesThumbnails != null) ? ((string)data.mesThumbnails.Start ?? "{Best}") : null, "Media Encoder Standard", "MesThumbnails.json", "{Best}", ref taskindex, specifiedStorageAccountName: JobHelpers.OutputStorageFromParam(data.mesThumbnails));

                // Hyperlapse
                OutputHyperlapse = JobHelpers.AddTask(execContext, _context, job, subclipasset, (data.hyperlapse == null) ? (string)data.hyperlapseSpeed : ((string)data.hyperlapse.speed ?? "8"), "Azure Media Hyperlapse", "Hyperlapse.json", "8", ref taskindex, specifiedStorageAccountName: JobHelpers.OutputStorageFromParam(data.hyperlapse));

                job.Submit();
                log.Info("Job Submitted");

                id++;
                ManifestHelpers.UpdateLastEndTime(table, starttime + duration, programid, id, program.State);

                log.Info($"Output MES index {OutputMES}");

                // Let store some data in altid of subclipped asset
                var sid = JobHelpers.ReturnId(job, OutputMES);
                log.Info($"SID {sid}");
                var subclipassetrefreshed = _context.Assets.Where(a => a.Id == sid).FirstOrDefault();
                log.Info($"subclipassetrefreshed ID {subclipassetrefreshed.Id}");
                subclipassetrefreshed.AlternateId = JsonConvert.SerializeObject(new ManifestHelpers.SubclipInfo()
                {
                    programId = programid, subclipStart = starttime, subclipDuration = duration
                });
                subclipassetrefreshed.Update();

                // Let store some data in altid of index assets
                var index1sid = JobHelpers.ReturnId(job, OutputIndex1);
                if (index1sid != null)
                {
                    var index1assetrefreshed = _context.Assets.Where(a => a.Id == index1sid).FirstOrDefault();
                    log.Info($"index1assetrefreshed ID {index1assetrefreshed.Id}");
                    index1assetrefreshed.AlternateId = JsonConvert.SerializeObject(new ManifestHelpers.SubclipInfo()
                    {
                        programId = programid, subclipStart = starttime, subclipDuration = duration
                    });
                    index1assetrefreshed.Update();
                }

                var index2sid = JobHelpers.ReturnId(job, OutputIndex2);
                if (index2sid != null)
                {
                    var index2assetrefreshed = _context.Assets.Where(a => a.Id == index2sid).FirstOrDefault();
                    log.Info($"index2assetrefreshed ID {index2assetrefreshed.Id}");
                    index2assetrefreshed.AlternateId = JsonConvert.SerializeObject(new ManifestHelpers.SubclipInfo()
                    {
                        programId = programid, subclipStart = starttime, subclipDuration = duration
                    });
                    index2assetrefreshed.Update();
                }

                // Get program URL
                var publishurlsmooth = MediaServicesHelper.GetValidOnDemandURI(_context, asset);

                if (publishurlsmooth != null)
                {
                    programUrl = publishurlsmooth.ToString();
                }

                NumberJobsQueue = _context.Jobs.Where(j => j.State == JobState.Queued).Count();
            }
            catch (Exception ex)
            {
                string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : "");
                log.Info($"ERROR: Exception {message}");
                return(req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message }));
            }

            log.Info("Job Id: " + job.Id);
            log.Info("Output asset Id: " + ((OutputMES > -1) ? JobHelpers.ReturnId(job, OutputMES) : JobHelpers.ReturnId(job, OutputPremium)));

            return(req.CreateResponse(HttpStatusCode.OK, new
            {
                triggerStart = triggerStart,
                jobId = job.Id,
                subclip = new
                {
                    assetId = JobHelpers.ReturnId(job, OutputMES),
                    taskId = JobHelpers.ReturnTaskId(job, OutputMES),
                    start = starttime,
                    duration = duration,
                },
                mesThumbnails = new
                {
                    assetId = JobHelpers.ReturnId(job, OutputMesThumbnails),
                    taskId = JobHelpers.ReturnTaskId(job, OutputMesThumbnails)
                },
                indexV1 = new
                {
                    assetId = JobHelpers.ReturnId(job, OutputIndex1),
                    taskId = JobHelpers.ReturnTaskId(job, OutputIndex1),
                    language = (string)data.indexV1Language
                },
                indexV2 = new
                {
                    assetId = JobHelpers.ReturnId(job, OutputIndex2),
                    taskId = JobHelpers.ReturnTaskId(job, OutputIndex2),
                    language = (string)data.indexV2Language,
                },
                ocr = new
                {
                    assetId = JobHelpers.ReturnId(job, OutputOCR),
                    taskId = JobHelpers.ReturnTaskId(job, OutputOCR)
                },
                faceDetection = new
                {
                    assetId = JobHelpers.ReturnId(job, OutputFaceDetection),
                    taskId = JobHelpers.ReturnTaskId(job, OutputFaceDetection)
                },
                faceRedaction = new
                {
                    assetId = JobHelpers.ReturnId(job, OutputFaceRedaction),
                    taskId = JobHelpers.ReturnTaskId(job, OutputFaceRedaction)
                },
                motionDetection = new
                {
                    assetId = JobHelpers.ReturnId(job, OutputMotion),
                    taskId = JobHelpers.ReturnTaskId(job, OutputMotion)
                },
                summarization = new
                {
                    assetId = JobHelpers.ReturnId(job, OutputSummarization),
                    taskId = JobHelpers.ReturnTaskId(job, OutputSummarization)
                },
                hyperlapse = new
                {
                    assetId = JobHelpers.ReturnId(job, OutputHyperlapse),
                    taskId = JobHelpers.ReturnTaskId(job, OutputHyperlapse)
                },
                videoAnnotation = new
                {
                    assetId = JobHelpers.ReturnId(job, OutputVideoAnnotation),
                    taskId = JobHelpers.ReturnTaskId(job, OutputVideoAnnotation)
                },
                contentModeration = new
                {
                    assetId = JobHelpers.ReturnId(job, OutputContentModeration),
                    taskId = JobHelpers.ReturnTaskId(job, OutputContentModeration)
                },

                channelName = channelName,
                programName = programName,
                programId = programid,
                programUrl = programUrl,
                programState = programState,
                programStateChanged = (lastProgramState != programState).ToString(),
                otherJobsQueue = NumberJobsQueue
            }));
        }
示例#5
0
        public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log)
        {
            {
                log.Info($"Webhook was triggered!");

                string jsonContent = await req.Content.ReadAsStringAsync();

                dynamic data = JsonConvert.DeserializeObject(jsonContent);

                log.Info(jsonContent);

                if (data.assetId == null)
                {
                    // for test
                    // data.assetId = "nb:cid:UUID:c0d770b4-1a69-43c4-a4e6-bc60d20ab0b2";
                    return(req.CreateResponse(HttpStatusCode.BadRequest, new {
                        error = "Please pass asset ID in the input object (assetId)"
                    }));
                }

                string playerUrl   = "";
                string smoothUrl   = "";
                string pathUrl     = "";
                string preferredSE = data.preferredSE;
                string serveType   = data.serveType;

                MediaServicesCredentials amsCredentials = new MediaServicesCredentials();
                log.Info($"Using Azure Media Service Rest API Endpoint : {amsCredentials.AmsRestApiEndpoint}");

                try {
                    AzureAdTokenCredentials tokenCredentials = new AzureAdTokenCredentials(amsCredentials.AmsAadTenantDomain,
                                                                                           new AzureAdClientSymmetricKey(amsCredentials.AmsClientId, amsCredentials.AmsClientSecret),
                                                                                           AzureEnvironments.AzureCloudEnvironment);

                    AzureAdTokenProvider tokenProvider = new AzureAdTokenProvider(tokenCredentials);

                    _context = new CloudMediaContext(amsCredentials.AmsRestApiEndpoint, tokenProvider);

                    // Get the asset
                    string assetid     = data.assetId;
                    var    outputAsset = _context.Assets.Where(a => a.Id == assetid).FirstOrDefault();

                    if (outputAsset == null)
                    {
                        log.Info($"Asset not found {assetid}");

                        return(req.CreateResponse(HttpStatusCode.BadRequest, new {
                            error = "Asset not found"
                        }));
                    }

                    // publish with a streaming locator (100 years)
                    log.Info(serveType);
                    if (serveType == "OnDemandOrigin")
                    {
                        IAccessPolicy readPolicy2    = _context.AccessPolicies.Create("readPolicy", TimeSpan.FromDays(365 * 100), AccessPermissions.Read);
                        ILocator      outputLocator2 = _context.Locators.CreateLocator(LocatorType.OnDemandOrigin, outputAsset, readPolicy2);

                        var publishurlsmooth = MediaServicesHelper.GetValidOnDemandURI(_context, outputAsset, preferredSE);
                        var publishurlpath   = MediaServicesHelper.GetValidOnDemandPath(_context, outputAsset, preferredSE);

                        if (outputLocator2 != null && publishurlsmooth != null)
                        {
                            smoothUrl = publishurlsmooth.ToString();
                            playerUrl = "https://ampdemo.azureedge.net/?url=" + HttpUtility.UrlEncode(smoothUrl);
                            log.Info($"smooth url : {smoothUrl}");
                        }

                        if (outputLocator2 != null && publishurlpath != null)
                        {
                            pathUrl = publishurlpath.ToString();
                            log.Info($"path url : {pathUrl}");
                        }
                    }
                    if (serveType == "sas")
                    {
                        IAccessPolicy readPolicy1    = _context.AccessPolicies.Create("readPolicy", TimeSpan.FromDays(365 * 100), AccessPermissions.Read);
                        ILocator      outputLocator1 = _context.Locators.CreateLocator(LocatorType.Sas, outputAsset, readPolicy1);
                    }
                } catch (Exception ex) {
                    string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : "");
                    log.Info($"ERROR: Exception {message}");
                    return(req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message }));
                }

                log.Info($"");
                return(req.CreateResponse(HttpStatusCode.OK, new {
                    playerUrl = playerUrl,
                    smoothUrl = smoothUrl,
                    pathUrl = pathUrl
                }));
            }
        }
示例#6
0
        public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log)
        {
            log.Info($"AMS v2 Function - Add Authorization Policy was triggered!");

            string jsonContent = await req.Content.ReadAsStringAsync();

            if (string.IsNullOrEmpty(jsonContent))
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass a JSON request body" }));
            }

            AuthorizationPolicyRequst data = JsonConvert.DeserializeObject <AuthorizationPolicyRequst>(jsonContent);

            // Validate input objects
            if (string.IsNullOrEmpty(data.b64Secret))
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass a base 64 symetric secret" }));
            }

            if (string.IsNullOrEmpty(data.tokenType))
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass the token type (SWT or JWT)" }));
            }

            if (string.IsNullOrEmpty(data.audience))
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass the audience value" }));
            }

            if (string.IsNullOrEmpty(data.issuer))
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass the issuer value" }));
            }

            if (data.config == null || data.config.Length < 1)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass the authorization option configuration" }));
            }

            IContentKeyAuthorizationPolicy result;

            try
            {
                result = GetTokenRestrictedAuthorizationPolicy(log, data);
                log.Info($"Out of auth policy code");
                if (result != null)
                {
                    log.Info($"Made auth policy");
                }
            }
            catch (Exception ex)
            {
                string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : "") + "\n" + ex.StackTrace;
                log.Info($"ERROR: Exception {message}");
                return(req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message }));
            }

            return(req.CreateResponse(HttpStatusCode.OK, new
            {
                authPolicyId = result.Id,
            }));
        }
示例#7
0
 public static string GetHexIV()
 {
     byte[] output = MediaServicesHelper.GetRandomBuffer(16);
     return(BitConverter.ToString(output).Replace("-", string.Empty));
 }
        public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log)
        {
            {
                log.Info($"Webhook was triggered!");

                // Init variables
                string vttUrl      = "";
                string pathUrl     = "";
                string ttmlUrl     = "";
                string vttContent  = "";
                string ttmlContent = "";
                string ttmlContentTimeCorrected = "";
                string vttContentTimeCorrected  = "";

                string jsonContent = await req.Content.ReadAsStringAsync();

                dynamic data = JsonConvert.DeserializeObject(jsonContent);

                log.Info(jsonContent);

                if (data.assetId == null)
                {
                    // for test
                    // data.assetId = "nb:cid:UUID:d9496372-32f5-430d-a4c6-d21ec3e01525";

                    return(req.CreateResponse(HttpStatusCode.BadRequest, new
                    {
                        error = "Please pass asset ID in the input object (AssetId)"
                    }));
                }

                MediaServicesCredentials amsCredentials = new MediaServicesCredentials();
                log.Info($"Using Azure Media Service Rest API Endpoint : {amsCredentials.AmsRestApiEndpoint}");

                try
                {
                    AzureAdTokenCredentials tokenCredentials = new AzureAdTokenCredentials(amsCredentials.AmsAadTenantDomain,
                                                                                           new AzureAdClientSymmetricKey(amsCredentials.AmsClientId, amsCredentials.AmsClientSecret),
                                                                                           AzureEnvironments.AzureCloudEnvironment);

                    AzureAdTokenProvider tokenProvider = new AzureAdTokenProvider(tokenCredentials);

                    _context = new CloudMediaContext(amsCredentials.AmsRestApiEndpoint, tokenProvider);


                    // Get the asset
                    string assetid     = data.assetId;
                    var    outputAsset = _context.Assets.Where(a => a.Id == assetid).FirstOrDefault();

                    if (outputAsset == null)
                    {
                        log.Info($"Asset not found {assetid}");
                        return(req.CreateResponse(HttpStatusCode.BadRequest, new
                        {
                            error = "Asset not found"
                        }));
                    }

                    var vttSubtitle  = outputAsset.AssetFiles.Where(a => a.Name.ToUpper().EndsWith(".VTT")).FirstOrDefault();
                    var ttmlSubtitle = outputAsset.AssetFiles.Where(a => a.Name.ToUpper().EndsWith(".TTML")).FirstOrDefault();

                    Uri publishurl = MediaServicesHelper.GetValidOnDemandPath(_context, outputAsset);
                    if (publishurl != null)
                    {
                        pathUrl = publishurl.ToString();
                    }
                    else
                    {
                        log.Info($"Asset not published");
                    }

                    if (vttSubtitle != null)
                    {
                        if (publishurl != null)
                        {
                            vttUrl = pathUrl + vttSubtitle.Name;
                            log.Info($"vtt url : {vttUrl}");
                        }
                        vttContent = MediaServicesHelper.ReturnContent(vttSubtitle);

                        if (data.timeOffset != null) // let's update the ttml with new timecode
                        {
                            var           tsoffset = TimeSpan.Parse((string)data.timeOffset);
                            string        arrow    = " --> ";
                            StringBuilder sb       = new StringBuilder();
                            string[]      delim    = { Environment.NewLine, "\n" }; // "\n" added in case you manually appended a newline
                            string[]      vttlines = vttContent.Split(delim, StringSplitOptions.None);

                            foreach (string vttline in vttlines)
                            {
                                string line = vttline;
                                if (vttline.Contains(arrow))
                                {
                                    TimeSpan begin = TimeSpan.Parse(vttline.Substring(0, vttline.IndexOf(arrow)));
                                    TimeSpan end   = TimeSpan.Parse(vttline.Substring(vttline.IndexOf(arrow) + 5));
                                    line = (begin + tsoffset).ToString(@"d\.hh\:mm\:ss\.fff") + arrow + (end + tsoffset).ToString(@"d\.hh\:mm\:ss\.fff");
                                }
                                sb.AppendLine(line);
                            }
                            vttContentTimeCorrected = sb.ToString();
                        }
                    }

                    if (ttmlSubtitle != null)
                    {
                        if (publishurl != null)
                        {
                            ttmlUrl = pathUrl + vttSubtitle.Name;
                            log.Info($"ttml url : {ttmlUrl}");
                        }
                        ttmlContent = MediaServicesHelper.ReturnContent(ttmlSubtitle);
                        if (data.timeOffset != null) // let's update the vtt with new timecode
                        {
                            var tsoffset = TimeSpan.Parse((string)data.timeOffset);
                            log.Info("tsoffset : " + tsoffset.ToString(@"d\.hh\:mm\:ss\.fff"));
                            XNamespace xmlns     = "http://www.w3.org/ns/ttml";
                            XDocument  docXML    = XDocument.Parse(ttmlContent);
                            var        tt        = docXML.Element(xmlns + "tt");
                            var        subtitles = docXML.Element(xmlns + "tt").Element(xmlns + "body").Element(xmlns + "div").Elements(xmlns + "p");
                            foreach (var sub in subtitles)
                            {
                                var begin = TimeSpan.Parse((string)sub.Attribute("begin"));
                                var end   = TimeSpan.Parse((string)sub.Attribute("end"));
                                sub.SetAttributeValue("end", (end + tsoffset).ToString(@"d\.hh\:mm\:ss\.fff"));
                                sub.SetAttributeValue("begin", (begin + tsoffset).ToString(@"d\.hh\:mm\:ss\.fff"));
                            }
                            ttmlContentTimeCorrected = docXML.Declaration.ToString() + Environment.NewLine + docXML.ToString();
                        }
                    }

                    if (ttmlContent != "" && vttContent != "" && data.deleteAsset != null && ((bool)data.deleteAsset))
                    // If asset deletion was asked
                    {
                        outputAsset.Delete();
                    }
                }
                catch (Exception ex)
                {
                    string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : "");
                    log.Info($"ERROR: Exception {message}");
                    return(req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message }));
                }

                log.Info($"");
                return(req.CreateResponse(HttpStatusCode.OK, new
                {
                    vttUrl = vttUrl,
                    ttmlUrl = ttmlUrl,
                    pathUrl = pathUrl,
                    ttmlDocument = ttmlContent,
                    ttmlDocumentWithOffset = ttmlContentTimeCorrected,
                    vttDocument = vttContent,
                    vttDocumentWithOffset = vttContentTimeCorrected
                }));
            }
        }
示例#9
0
        public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log)
        {
            log.Info($"Webhook was triggered!");

            string jsonContent = await req.Content.ReadAsStringAsync();

            dynamic data = JsonConvert.DeserializeObject(jsonContent);

            log.Info("Request : " + jsonContent);

            // Validate input objects
            int delay = 5000;

            if (data.targetStorageAccountName == null)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass targetStorageAccountName in the input object" }));
            }
            if (data.targetStorageAccountKey == null)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass targetStorageAccountKey in the input object" }));
            }
            if (data.targetContainer == null)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass targetContainer in the input object" }));
            }
            if (data.delay != null)
            {
                delay = data.delay;
            }
            log.Info("Input - DestinationContainer : " + data.targetContainer);
            //log.Info("delay : " + delay);

            log.Info($"Wait " + delay + "(ms)");
            System.Threading.Thread.Sleep(delay);

            string targetStorageAccountName = data.targetStorageAccountName;
            string targetStorageAccountKey  = data.targetStorageAccountKey;
            string targetContainer          = data.targetContainer;


            CopyStatus copyStatus = CopyStatus.Success;

            try
            {
                CloudBlobContainer destinationBlobContainer = CopyBlobHelpers.GetCloudBlobContainer(targetStorageAccountName, targetStorageAccountKey, targetContainer);

                string blobPrefix = null;

                if (!string.IsNullOrWhiteSpace((string)data.fileNamePrefix))
                {
                    blobPrefix = (string)data.fileNamePrefix;
                    log.Info($"{blobPrefix}");
                }

                bool useFlatBlobListing = true;
                var  destBlobList       = destinationBlobContainer.ListBlobs(blobPrefix, useFlatBlobListing, BlobListingDetails.Copy);
                foreach (var dest in destBlobList)
                {
                    var destBlob = dest as CloudBlob;
                    if (destBlob.CopyState.Status == CopyStatus.Aborted || destBlob.CopyState.Status == CopyStatus.Failed)
                    {
                        // Log the copy status description for diagnostics and restart copy
                        destBlob.StartCopyAsync(destBlob.CopyState.Source);
                        copyStatus = CopyStatus.Pending;
                    }
                    else if (destBlob.CopyState.Status == CopyStatus.Pending)
                    {
                        // We need to continue waiting for this pending copy
                        // However, let us log copy state for diagnostics
                        copyStatus = CopyStatus.Pending;
                    }
                    // else we completed this pending copy
                }
            }
            catch (Exception ex)
            {
                string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : "");
                log.Info($"ERROR: Exception {message}");
                return(req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message }));
            }

            return(req.CreateResponse(HttpStatusCode.OK, new
            {
                copyStatus = copyStatus,
                isRunning = (copyStatus == CopyStatus.Pending).ToString(),
                isSuccessful = (copyStatus == CopyStatus.Success).ToString()
            }));
        }
        public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log)


        {
            log.Info($"Webhook was triggered!");

            string jsonContent = await req.Content.ReadAsStringAsync();

            dynamic data = JsonConvert.DeserializeObject(jsonContent);

            log.Info("Request : " + jsonContent);

            MediaServicesCredentials amsCredentials = new MediaServicesCredentials();

            log.Info($"Using Azure Media Service Rest API Endpoint : {amsCredentials.AmsRestApiEndpoint}");

            // Validate input objects
            if (data.assetId == null)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass assetId in the input object" }));
            }

            string startsWith = data.startsWith;
            string endsWith   = data.endsWith;


            string assetId = data.assetId;

            IAsset asset = null;

            try
            {
                AzureAdTokenCredentials tokenCredentials = new AzureAdTokenCredentials(amsCredentials.AmsAadTenantDomain,
                                                                                       new AzureAdClientSymmetricKey(amsCredentials.AmsClientId, amsCredentials.AmsClientSecret),
                                                                                       AzureEnvironments.AzureCloudEnvironment);

                AzureAdTokenProvider tokenProvider = new AzureAdTokenProvider(tokenCredentials);

                _context = new CloudMediaContext(amsCredentials.AmsRestApiEndpoint, tokenProvider);

                // Find the Asset
                asset = _context.Assets.Where(a => a.Id == assetId).FirstOrDefault();
                if (asset == null)
                {
                    return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Asset not found" }));
                }

                var files = asset.AssetFiles.ToList().Where(f => ((string.IsNullOrEmpty(endsWith) || f.Name.EndsWith(endsWith)) && (string.IsNullOrEmpty(startsWith) || f.Name.StartsWith(startsWith))));

                foreach (var file in files)
                {
                    file.Delete();
                    log.Info($"Deleted file: {file.Name}");
                }
            }
            catch (Exception ex)
            {
                string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : "");
                log.Info($"ERROR: Exception {message}");
                return(req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message }));
            }

            return(req.CreateResponse(HttpStatusCode.OK));
        }
示例#11
0
        public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log)
        {
            log.Info($"AMS v2 Function - Add Dynamic Encryption was triggered!");

            string jsonContent = await req.Content.ReadAsStringAsync();

            dynamic data = JsonConvert.DeserializeObject(jsonContent);

            // Validate input objects
            if (data.assetId == null && data.programId == null && data.channelName == null && data.programName == null)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass assetId or programID or channelName/programName in the input object" }));
            }

            if (data.contentKeyAuthorizationPolicyId == null)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass contentKeyAuthorizationPolicyId in the input object" }));
            }

            if (data.assetDeliveryPolicyId == null)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass assetDeliveryPolicyId in the input object" }));
            }

            if (data.contentKeyType == null)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass contentKeyType in the input object" }));
            }

            string assetId     = data.assetId;
            string programId   = data.programId;
            string channelName = data.channelName;
            string programName = data.programName;
            string contentKeyAuthorizationPolicyId = data.contentKeyAuthorizationPolicyId;
            string assetDeliveryPolicyId           = data.assetDeliveryPolicyId;
            string contentKeyTypeName = data.contentKeyType;
            string contentKeyId       = data.keyId;
            string contentKeySecret   = data.contentKey;

            if (!MediaServicesHelper.AMSContentKeyType.ContainsKey(contentKeyTypeName))
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass a valid contentKeyType in the input object" }));
            }


            ContentKeyType contentKeyType = MediaServicesHelper.AMSContentKeyType[contentKeyTypeName];

            if (contentKeyType != ContentKeyType.CommonEncryption && contentKeyType != ContentKeyType.CommonEncryptionCbcs && contentKeyType != ContentKeyType.EnvelopeEncryption)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass a valid contentKeyType in the input object" }));
            }


            string contentKeyName = null;

            if (data.contentKeyName != null)
            {
                contentKeyName = data.contentKeyName;
            }

            MediaServicesCredentials amsCredentials = new MediaServicesCredentials();
            IAsset asset = null;
            IContentKeyAuthorizationPolicy ckaPolicy = null;
            IAssetDeliveryPolicy           adPolicy  = null;
            IContentKey contentKey = null;

            try
            {
                // Load AMS account context
                log.Info($"Using AMS v2 REST API Endpoint : {amsCredentials.AmsRestApiEndpoint.ToString()}");

                AzureAdTokenCredentials tokenCredentials = new AzureAdTokenCredentials(amsCredentials.AmsAadTenantDomain,
                                                                                       new AzureAdClientSymmetricKey(amsCredentials.AmsClientId, amsCredentials.AmsClientSecret),
                                                                                       AzureEnvironments.AzureCloudEnvironment);
                AzureAdTokenProvider tokenProvider = new AzureAdTokenProvider(tokenCredentials);
                _context = new CloudMediaContext(amsCredentials.AmsRestApiEndpoint, tokenProvider);

                // Let's get the asset
                if (assetId != null)
                {
                    // Get the Asset, ContentKeyAuthorizationPolicy, AssetDeliveryPolicy
                    asset = _context.Assets.Where(a => a.Id == assetId).FirstOrDefault();
                    if (asset == null)
                    {
                        return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Asset not found" }));
                    }
                }
                else if (programId != null)
                {
                    var program = _context.Programs.Where(p => p.Id == programId).FirstOrDefault();
                    if (program == null)
                    {
                        log.Info("Program not found");
                        return(req.CreateResponse(HttpStatusCode.BadRequest, new
                        {
                            error = "Program not found"
                        }));
                    }
                    asset = program.Asset;
                }
                else // with channelName and programName
                {
                    // find the Channel, Program and Asset
                    var channel = _context.Channels.Where(c => c.Name == channelName).FirstOrDefault();
                    if (channel == null)
                    {
                        log.Info("Channel not found");
                        return(req.CreateResponse(HttpStatusCode.BadRequest, new
                        {
                            error = "Channel not found"
                        }));
                    }

                    var program = channel.Programs.Where(p => p.Name == programName).FirstOrDefault();
                    if (program == null)
                    {
                        log.Info("Program not found");
                        return(req.CreateResponse(HttpStatusCode.BadRequest, new
                        {
                            error = "Program not found"
                        }));
                    }
                    asset = program.Asset;
                }

                log.Info($"Using asset Id : {asset.Id}");

                ckaPolicy = _context.ContentKeyAuthorizationPolicies.Where(p => p.Id == contentKeyAuthorizationPolicyId).Single();
                if (ckaPolicy == null)
                {
                    return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "ContentKeyAuthorizationPolicy not found" }));
                }
                adPolicy = _context.AssetDeliveryPolicies.Where(p => p.Id == assetDeliveryPolicyId).Single();
                if (adPolicy == null)
                {
                    return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "AssetDeliveryPolicy not found" }));
                }

                if (contentKeyId != null)
                {
                    string keyiddwitprefix = "";

                    if (contentKeyId.StartsWith("nb:kid:UUID:"))
                    {
                        keyiddwitprefix = contentKeyId;
                        contentKeyId    = contentKeyId.Substring(12);
                    }
                    else
                    {
                        keyiddwitprefix = "nb:kid:UUID:" + contentKeyId;
                    }

                    // let's retrieve the key if it exists already
                    contentKey = _context.ContentKeys.Where(k => k.Id == keyiddwitprefix).FirstOrDefault();
                }

                if (contentKey == null) // let's create it as it was not found or delivered to the function
                {
                    switch (contentKeyType)
                    {
                    case ContentKeyType.CommonEncryption:
                        if (contentKeyName == null)
                        {
                            contentKeyName = "Common Encryption ContentKey";
                        }
                        contentKey = MediaServicesHelper.CreateContentKey(_context, contentKeyName, ContentKeyType.CommonEncryption, contentKeyId, contentKeySecret);
                        break;

                    case ContentKeyType.CommonEncryptionCbcs:
                        if (contentKeyName == null)
                        {
                            contentKeyName = "Common Encryption CBCS ContentKey";
                        }
                        contentKey = MediaServicesHelper.CreateContentKey(_context, contentKeyName, ContentKeyType.CommonEncryptionCbcs, contentKeyId, contentKeySecret);
                        break;

                    case ContentKeyType.EnvelopeEncryption:
                        if (contentKeyName == null)
                        {
                            contentKeyName = "Envelope Encryption ContentKey";
                        }
                        contentKey = MediaServicesHelper.CreateContentKey(_context, contentKeyName, ContentKeyType.EnvelopeEncryption, contentKeyId, contentKeySecret);
                        break;
                    }
                }

                asset.ContentKeys.Add(contentKey);
                contentKey.AuthorizationPolicyId = ckaPolicy.Id;
                contentKey = contentKey.UpdateAsync().Result;
                asset.DeliveryPolicies.Add(adPolicy);
            }
            catch (Exception ex)
            {
                string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : "");
                log.Info($"ERROR: Exception {message}");
                return(req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message }));
            }

            return(req.CreateResponse(HttpStatusCode.OK, new
            {
                contentKeyId = contentKey.Id,
                assetId = asset.Id
            }));
        }
示例#12
0
        public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log)
        {
            log.Info($"Webhook was triggered!");

            string jsonContent = await req.Content.ReadAsStringAsync();

            dynamic data = JsonConvert.DeserializeObject(jsonContent);

            log.Info(jsonContent);

            var attachedstoragecred = KeyHelper.ReturnStorageCredentials();

            if (data.assetId == null)
            {
                // for test
                // data.Path = "/input/WP_20121015_081924Z.mp4";

                return(req.CreateResponse(HttpStatusCode.BadRequest, new
                {
                    error = "Please pass assetId in the input object"
                }));
            }

            MediaServicesCredentials amsCredentials = new MediaServicesCredentials();

            log.Info($"Using Azure Media Service Rest API Endpoint : {amsCredentials.AmsRestApiEndpoint}");

            try
            {
                AzureAdTokenCredentials tokenCredentials = new AzureAdTokenCredentials(amsCredentials.AmsAadTenantDomain,
                                                                                       new AzureAdClientSymmetricKey(amsCredentials.AmsClientId, amsCredentials.AmsClientSecret),
                                                                                       AzureEnvironments.AzureCloudEnvironment);

                AzureAdTokenProvider tokenProvider = new AzureAdTokenProvider(tokenCredentials);

                _context = new CloudMediaContext(amsCredentials.AmsRestApiEndpoint, tokenProvider);



                // Step 1:  Copy the Blob into a new Input Asset for the Job
                // ***NOTE: Ideally we would have a method to ingest a Blob directly here somehow.
                // using code from this sample - https://azure.microsoft.com/en-us/documentation/articles/media-services-copying-existing-blob/

                // Get the asset
                string assetid = data.assetId;
                var    asset   = _context.Assets.Where(a => a.Id == assetid).FirstOrDefault();

                if (asset == null)
                {
                    log.Info($"Asset not found {assetid}");

                    return(req.CreateResponse(HttpStatusCode.BadRequest, new
                    {
                        error = "Asset not found"
                    }));
                }

                log.Info("Asset found, ID: " + asset.Id);


                string storname = amsCredentials.StorageAccountName;
                string storkey  = amsCredentials.StorageAccountKey;
                if (asset.StorageAccountName != amsCredentials.StorageAccountName)
                {
                    if (attachedstoragecred.ContainsKey(asset.StorageAccountName)) // asset is using another storage than default but we have the key
                    {
                        storname = asset.StorageAccountName;
                        storkey  = attachedstoragecred[storname];
                    }
                    else // we don't have the key for that storage
                    {
                        log.Info($"Face redaction Asset is in {asset.StorageAccountName} and key is not provided in MediaServicesAttachedStorageCredentials application settings");
                        return(req.CreateResponse(HttpStatusCode.BadRequest, new
                        {
                            error = "Storage key is missing"
                        }));
                    }
                }


                CloudBlobContainer assetContainer = CopyBlobHelpers.GetCloudBlobContainer(storname, storkey, asset.Uri.Segments[1]);
                foreach (String seg in asset.Uri.Segments)
                {
                    log.Info($"> asset.Uri.Segments :" + seg);
                }

                /*IEnumerable<CloudBlobContainer> containers = blobClient.ListContainers();
                 * foreach (CloudBlobContainer item in containers)
                 * {
                 *  foreach (IListBlobItem blob in item.ListBlobs())
                 *  {
                 *      blobs.Add(string.Format("{0}", blob.Uri.Segments[2]));
                 *  }
                 * }
                 */
                /*
                 * //Get a reference to the storage account that is associated with the Media Services account.
                 * StorageCredentials mediaServicesStorageCredentials =
                 *  new StorageCredentials(_storageAccountName, _storageAccountKey);
                 * var _destinationStorageAccount = new CloudStorageAccount(mediaServicesStorageCredentials, false);
                 *
                 * CloudBlobClient destBlobStorage = _destinationStorageAccount.CreateCloudBlobClient();
                 *
                 * // Get the destination asset container reference
                 * string destinationContainerName = asset.Uri.Segments[1];
                 * log.Info($"destinationContainerName : {destinationContainerName}");
                 *
                 * CloudBlobContainer assetContainer = destBlobStorage.GetContainerReference(destinationContainerName);
                 */

                log.Info($"assetContainer retrieved");

                // Get hold of the destination blobs
                var blobsPseudo = assetContainer.ListBlobs();
                log.Info($"blobsPseudo retrieved");

                log.Info($"blobsPseudo count : {blobsPseudo.Count()}");

                var aflist = asset.AssetFiles.ToList().Select(af => af.Name);

                /*   OLD WAY
                 *   foreach (CloudBlockBlob blob in blobs)
                 * {
                 *     if (aflist.Contains(blob.Name))
                 *     {
                 *         var assetFile = asset.AssetFiles.Where(af => af.Name == blob.Name).FirstOrDefault();
                 *         assetFile.ContentFileSize = blob.Properties.Length;
                 *         assetFile.Update();
                 *         log.Info($"Asset file updated : {assetFile.Name}");
                 *     }
                 *     else
                 *     {
                 *         var assetFile = asset.AssetFiles.Create(blob.Name);
                 *         assetFile.ContentFileSize = blob.Properties.Length;
                 *         assetFile.Update();
                 *         log.Info($"Asset file created : {assetFile.Name}");
                 *     }
                 * }
                 */
                log.Info($"Witness 3 ");
                //Adding mecanic to list all sub dir (original just lists elements in given folder and consider them as blob even if they are subdirs)
                //var folders = blobs.Where(b => b as CloudBlobDirectory != null).ToList();

                //this is supposedly a 2 levels scenario... might not suits our case yet (one more level?)
                foreach (IListBlobItem blobItem in blobsPseudo)
                {
                    log.Info($"blobItem found : ");
                    if (blobItem is CloudBlobDirectory)
                    {
                        CloudBlobDirectory          directory = (CloudBlobDirectory)blobItem;
                        IEnumerable <IListBlobItem> blobs     = directory.ListBlobs();
                        //ICloudBlob bi;
                        foreach (var item in blobs)
                        {
                            log.Info($"item StorageUri : " + item.StorageUri);
                            CloudBlockBlob blob = (CloudBlockBlob)item;
                            blob.FetchAttributes();
                            log.Info($"Blob found uri : " + blob.Uri);
                            log.Info($"Blob found Name : " + blob.Name);
                            String potentialName = Path.GetFileName(blob.Name);
                            log.Info($"Blob potentialName : " + potentialName);
                            String normalizedName = potentialName;
                            if (aflist.Contains(normalizedName))
                            {
                                log.Info($" aflist.Contains Blob found Name : " + normalizedName);
                                var assetFile = asset.AssetFiles.Where(af => af.Name == normalizedName).FirstOrDefault();
                                assetFile.ContentFileSize = blob.Properties.Length;
                                assetFile.Update();
                                log.Info($"Asset file updated : {normalizedName}");
                            }
                            else
                            {
                                log.Info($"Create Blob found Name : " + normalizedName);

                                var assetFile = asset.AssetFiles.Create(normalizedName);
                                assetFile.ContentFileSize = blob.Properties.Length;
                                assetFile.Update();
                                log.Info($"Asset file created : {normalizedName}");
                            }
                        }
                    }
                    else
                    {
                        //TODO redefine !
                        CloudBlockBlob blob = (CloudBlockBlob)blobItem;
                        blob.FetchAttributes();
                        log.Info($"Blob2 found uri : " + blob.Uri);
                        log.Info($"Blob2 found Name : " + blob.Name);
                        if (aflist.Contains(blob.Name))
                        {
                            var assetFile = asset.AssetFiles.Where(af => af.Name == blob.Name).FirstOrDefault();
                            assetFile.ContentFileSize = blob.Properties.Length;
                            assetFile.Update();
                            log.Info($"Asset2 file updated : {assetFile.Name}");
                        }
                        else
                        {
                            var assetFile = asset.AssetFiles.Create(blob.Name);
                            assetFile.ContentFileSize = blob.Properties.Length;
                            assetFile.Update();
                            log.Info($"Asset2 file created : {assetFile.Name}");
                        }
                    }
                }

                asset.Update();
                MediaServicesHelper.SetAFileAsPrimary(asset);

                log.Info("Asset updated");
            }
            catch (Exception ex)
            {
                string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : "");
                log.Info($"ERROR: Exception {message}");
                return(req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message }));
            }

            return(req.CreateResponse(HttpStatusCode.OK));
        }
示例#13
0
        public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log)
        {
            log.Info($"Webhook was triggered!");

            string jsonContent = await req.Content.ReadAsStringAsync();

            dynamic data = JsonConvert.DeserializeObject(jsonContent);

            log.Info(jsonContent);

            if (data.jobId == null && data.assetId == null)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new
                {
                    error = "Please pass job Id and/or asset Id of the objects to delete"
                }));
            }

            MediaServicesCredentials amsCredentials = new MediaServicesCredentials();

            log.Info($"Using Azure Media Service Rest API Endpoint : {amsCredentials.AmsRestApiEndpoint}");

            try
            {
                AzureAdTokenCredentials tokenCredentials = new AzureAdTokenCredentials(amsCredentials.AmsAadTenantDomain,
                                                                                       new AzureAdClientSymmetricKey(amsCredentials.AmsClientId, amsCredentials.AmsClientSecret),
                                                                                       AzureEnvironments.AzureCloudEnvironment);

                AzureAdTokenProvider tokenProvider = new AzureAdTokenProvider(tokenCredentials);

                _context = new CloudMediaContext(amsCredentials.AmsRestApiEndpoint, tokenProvider);
            }
            catch (Exception ex)
            {
                log.Info($"Exception {ex}");
                return(req.CreateResponse(HttpStatusCode.InternalServerError, new
                {
                    Error = ex.ToString()
                }));
            }

            try
            {
                if (data.jobId != null)
                {
                    var jobids = (string)data.jobId;
                    foreach (string jobi in jobids.Split(','))
                    {
                        log.Info($"Using job Id : {jobi}");
                        var job = _context.Jobs.Where(j => j.Id == jobi).FirstOrDefault();
                        if (job != null)
                        {
                            job.Delete();
                            log.Info("Job deleted.");
                        }
                        else
                        {
                            log.Info("Job not found!");
                        }
                    }
                }

                if (data.assetId != null)
                {
                    var assetids = (string)data.assetId;
                    foreach (string asseti in assetids.Split(','))
                    {
                        log.Info($"Using asset Id : {asseti}");
                        var asset = _context.Assets.Where(a => a.Id == asseti).FirstOrDefault();
                        if (asset != null)
                        {
                            asset.Delete();
                            log.Info("Asset deleted.");
                        }
                        else
                        {
                            log.Info("Asset not found!");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : "");
                log.Info($"ERROR: Exception {message}");
                return(req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message }));
            }

            return(req.CreateResponse(HttpStatusCode.OK, new
            {
            }));
        }
示例#14
0
        public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log)
        {
            log.Info($"Webhook was triggered!");

            string jsonContent = await req.Content.ReadAsStringAsync();

            dynamic data = JsonConvert.DeserializeObject(jsonContent);

            log.Info(jsonContent);

            var attachedstoragecred = KeyHelper.ReturnStorageCredentials();

            if (data.assetId == null)
            {
                // for test
                // data.Path = "/input/WP_20121015_081924Z.mp4";

                return(req.CreateResponse(HttpStatusCode.BadRequest, new
                {
                    error = "Please pass assetId in the input object"
                }));
            }

            MediaServicesCredentials amsCredentials = new MediaServicesCredentials();

            log.Info($"Using Azure Media Service Rest API Endpoint : {amsCredentials.AmsRestApiEndpoint}");

            try
            {
                AzureAdTokenCredentials tokenCredentials = new AzureAdTokenCredentials(amsCredentials.AmsAadTenantDomain,
                                                                                       new AzureAdClientSymmetricKey(amsCredentials.AmsClientId, amsCredentials.AmsClientSecret),
                                                                                       AzureEnvironments.AzureCloudEnvironment);

                AzureAdTokenProvider tokenProvider = new AzureAdTokenProvider(tokenCredentials);

                _context = new CloudMediaContext(amsCredentials.AmsRestApiEndpoint, tokenProvider);



                // Step 1:  Copy the Blob into a new Input Asset for the Job
                // ***NOTE: Ideally we would have a method to ingest a Blob directly here somehow.
                // using code from this sample - https://azure.microsoft.com/en-us/documentation/articles/media-services-copying-existing-blob/

                // Get the asset
                string assetid = data.assetId;
                var    asset   = _context.Assets.Where(a => a.Id == assetid).FirstOrDefault();

                if (asset == null)
                {
                    log.Info($"Asset not found {assetid}");

                    return(req.CreateResponse(HttpStatusCode.BadRequest, new
                    {
                        error = "Asset not found"
                    }));
                }

                log.Info("Asset found, ID: " + asset.Id);


                string storname = amsCredentials.StorageAccountName;
                string storkey  = amsCredentials.StorageAccountKey;
                if (asset.StorageAccountName != amsCredentials.StorageAccountName)
                {
                    if (attachedstoragecred.ContainsKey(asset.StorageAccountName)) // asset is using another storage than default but we have the key
                    {
                        storname = asset.StorageAccountName;
                        storkey  = attachedstoragecred[storname];
                    }
                    else // we don't have the key for that storage
                    {
                        log.Info($"Face redaction Asset is in {asset.StorageAccountName} and key is not provided in MediaServicesAttachedStorageCredentials application settings");
                        return(req.CreateResponse(HttpStatusCode.BadRequest, new
                        {
                            error = "Storage key is missing"
                        }));
                    }
                }

                CloudBlobContainer assetContainer = CopyBlobHelpers.GetCloudBlobContainer(storname, storkey, asset.Uri.Segments[1]);

                /*
                 * //Get a reference to the storage account that is associated with the Media Services account.
                 * StorageCredentials mediaServicesStorageCredentials =
                 *  new StorageCredentials(_storageAccountName, _storageAccountKey);
                 * var _destinationStorageAccount = new CloudStorageAccount(mediaServicesStorageCredentials, false);
                 *
                 * CloudBlobClient destBlobStorage = _destinationStorageAccount.CreateCloudBlobClient();
                 *
                 * // Get the destination asset container reference
                 * string destinationContainerName = asset.Uri.Segments[1];
                 * log.Info($"destinationContainerName : {destinationContainerName}");
                 *
                 * CloudBlobContainer assetContainer = destBlobStorage.GetContainerReference(destinationContainerName);
                 */

                log.Info($"assetContainer retrieved");

                // Get hold of the destination blobs
                var blobs = assetContainer.ListBlobs();
                log.Info($"blobs retrieved");

                log.Info($"blobs count : {blobs.Count()}");

                var aflist = asset.AssetFiles.ToList().Select(af => af.Name);

                foreach (CloudBlockBlob blob in blobs)
                {
                    if (aflist.Contains(blob.Name))
                    {
                        var assetFile = asset.AssetFiles.Where(af => af.Name == blob.Name).FirstOrDefault();
                        assetFile.ContentFileSize = blob.Properties.Length;
                        assetFile.Update();
                        log.Info($"Asset file updated : {assetFile.Name}");
                    }
                    else
                    {
                        var assetFile = asset.AssetFiles.Create(blob.Name);
                        assetFile.ContentFileSize = blob.Properties.Length;
                        assetFile.Update();
                        log.Info($"Asset file created : {assetFile.Name}");
                    }
                }

                asset.Update();
                MediaServicesHelper.SetAFileAsPrimary(asset);

                log.Info("Asset updated");
            }
            catch (Exception ex)
            {
                string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : "");
                log.Info($"ERROR: Exception {message}");
                return(req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message }));
            }

            return(req.CreateResponse(HttpStatusCode.OK));
        }
        public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log, Microsoft.Azure.WebJobs.ExecutionContext execContext)
        {
            log.Info($"Webhook was triggered!");

            string jsonContent = await req.Content.ReadAsStringAsync();

            dynamic data = JsonConvert.DeserializeObject(jsonContent);

            log.Info(jsonContent);

            string startsWith = data.startsWith;
            string endsWith   = data.endsWith;
            IAsset asset      = null;

            if (data.assetId == null)
            {
                // for test
                // data.assetId = "nb:cid:UUID:c0d770b4-1a69-43c4-a4e6-bc60d20ab0b2";
                return(req.CreateResponse(HttpStatusCode.BadRequest, new
                {
                    error = "Please pass asset ID in the input object (assetId)"
                }));
            }

            MediaServicesCredentials amsCredentials = new MediaServicesCredentials();

            log.Info($"Using Azure Media Service Rest API Endpoint : {amsCredentials.AmsRestApiEndpoint}");

            try
            {
                AzureAdTokenCredentials tokenCredentials = new AzureAdTokenCredentials(amsCredentials.AmsAadTenantDomain,
                                                                                       new AzureAdClientSymmetricKey(amsCredentials.AmsClientId, amsCredentials.AmsClientSecret),
                                                                                       AzureEnvironments.AzureCloudEnvironment);

                AzureAdTokenProvider tokenProvider = new AzureAdTokenProvider(tokenCredentials);

                _context = new CloudMediaContext(amsCredentials.AmsRestApiEndpoint, tokenProvider);

                // Get the asset
                string assetid = data.assetId;
                asset = _context.Assets.Where(a => a.Id == assetid).FirstOrDefault();

                if (asset == null)
                {
                    log.Info($"Asset not found {assetid}");

                    return(req.CreateResponse(HttpStatusCode.BadRequest, new
                    {
                        error = "Asset not found"
                    }));
                }

                // set alternate id
                if (data.alternateId != null)
                {
                    asset.AlternateId = (string)data.alternateId;
                    asset.Update();
                }
            }

            catch (Exception ex)
            {
                string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : "");
                log.Info($"ERROR: Exception {message}");
                return(req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message }));
            }


            log.Info($"");
            return(req.CreateResponse(HttpStatusCode.OK, new
            {
            }));
        }
示例#16
0
        public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log)
        {
            log.Info($"Webhook was triggered!");

            string jsonContent = await req.Content.ReadAsStringAsync();

            dynamic data = JsonConvert.DeserializeObject(jsonContent);

            log.Info("Request : " + jsonContent);

            var attachedstoragecred = KeyHelper.ReturnStorageCredentials();

            // Validate input objects
            if (data.assetId == null)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass assetId in the input object" }));
            }

            if (data.fileName == null && data.fileNames == null)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass fileName or fileNames in the input object" }));
            }
            if (data.sourceStorageAccountName == null)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass sourceStorageAccountName in the input object" }));
            }
            if (data.sourceStorageAccountKey == null)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass sourceStorageAccountKey in the input object" }));
            }
            if (data.sourceContainer == null)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass sourceContainer in the input object" }));
            }

            log.Info("Input - sourceStorageAccountName : " + data.sourceStorageAccountName);
            log.Info("Input - sourceStorageAccountKey : " + data.sourceStorageAccountKey);
            log.Info("Input - sourceContainer : " + data.sourceContainer);

            string _sourceStorageAccountName = data.sourceStorageAccountName;
            string _sourceStorageAccountKey  = data.sourceStorageAccountKey;
            string assetId     = data.assetId;
            bool   missingBlob = false;

            IAsset          newAsset = null;
            IIngestManifest manifest = null;

            MediaServicesCredentials amsCredentials = new MediaServicesCredentials();

            log.Info($"Using Azure Media Service Rest API Endpoint : {amsCredentials.AmsRestApiEndpoint}");

            try
            {
                AzureAdTokenCredentials tokenCredentials = new AzureAdTokenCredentials(amsCredentials.AmsAadTenantDomain,
                                                                                       new AzureAdClientSymmetricKey(amsCredentials.AmsClientId, amsCredentials.AmsClientSecret),
                                                                                       AzureEnvironments.AzureCloudEnvironment);

                AzureAdTokenProvider tokenProvider = new AzureAdTokenProvider(tokenCredentials);

                _context = new CloudMediaContext(amsCredentials.AmsRestApiEndpoint, tokenProvider);


                // Find the Asset
                newAsset = _context.Assets.Where(a => a.Id == assetId).FirstOrDefault();
                if (newAsset == null)
                {
                    return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Asset not found" }));
                }


                // Setup blob container
                CloudBlobContainer sourceBlobContainer = CopyBlobHelpers.GetCloudBlobContainer(_sourceStorageAccountName, _sourceStorageAccountKey, (string)data.sourceContainer);

                string storname = amsCredentials.StorageAccountName;
                string storkey  = amsCredentials.StorageAccountKey;
                if (newAsset.StorageAccountName != amsCredentials.StorageAccountName)
                {
                    if (attachedstoragecred.ContainsKey(newAsset.StorageAccountName)) // asset is using another storage than default but we have the key
                    {
                        storname = newAsset.StorageAccountName;
                        storkey  = attachedstoragecred[storname];
                    }
                    else // we don't have the key for that storage
                    {
                        log.Info($"Face redaction Asset is in {newAsset.StorageAccountName} and key is not provided in MediaServicesAttachedStorageCredentials application settings");
                        return(req.CreateResponse(HttpStatusCode.BadRequest, new
                        {
                            error = "Storage key is missing"
                        }));
                    }
                }

                CloudBlobContainer destinationBlobContainer = CopyBlobHelpers.GetCloudBlobContainer(storname, storkey, newAsset.Uri.Segments[1]);

                sourceBlobContainer.CreateIfNotExists();

                if (data.fileName != null)
                {
                    string fileName = (string)data.fileName;

                    CloudBlob sourceBlob = sourceBlobContainer.GetBlockBlobReference(fileName);

                    if (data.wait != null && (bool)data.wait)
                    {
                        for (int i = 1; i <= 3; i++) // let's wait 3 times 5 seconds (15 seconds)
                        {
                            if (sourceBlob.Exists())
                            {
                                break;
                            }

                            log.Info("Waiting 5 s...");
                            System.Threading.Thread.Sleep(5 * 1000);
                            sourceBlob = sourceBlobContainer.GetBlockBlobReference(fileName);
                        }
                    }

                    if (sourceBlob.Exists())
                    {
                        CloudBlob destinationBlob = destinationBlobContainer.GetBlockBlobReference(fileName);

                        if (destinationBlobContainer.CreateIfNotExists())
                        {
                            log.Info("container created");
                            destinationBlobContainer.SetPermissions(new BlobContainerPermissions
                            {
                                PublicAccess = BlobContainerPublicAccessType.Blob
                            });
                        }
                        CopyBlobHelpers.CopyBlobAsync(sourceBlob, destinationBlob);
                    }
                    else
                    {
                        missingBlob = true;
                    }
                }

                if (data.fileNames != null)
                {
                    foreach (var file in data.fileNames)
                    {
                        string    fileName   = (string)file;
                        CloudBlob sourceBlob = sourceBlobContainer.GetBlockBlobReference(fileName);
                        if (sourceBlob.Exists())
                        {
                            CloudBlob destinationBlob = destinationBlobContainer.GetBlockBlobReference(fileName);

                            if (destinationBlobContainer.CreateIfNotExists())
                            {
                                log.Info("container created");
                                destinationBlobContainer.SetPermissions(new BlobContainerPermissions
                                {
                                    PublicAccess = BlobContainerPublicAccessType.Blob
                                });
                            }
                            CopyBlobHelpers.CopyBlobAsync(sourceBlob, destinationBlob);
                        }
                        else
                        {
                            missingBlob = true;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : "");
                log.Info($"ERROR: Exception {message}");
                return(req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message }));
            }


            return(req.CreateResponse(HttpStatusCode.OK, new
            {
                destinationContainer = newAsset.Uri.Segments[1],
                missingBlob = missingBlob.ToString()
            }));
        }
        public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log)
        {
            log.Info($"Webhook was triggered!");

            // Init variables

            string jsonContent = await req.Content.ReadAsStringAsync();

            dynamic data = JsonConvert.DeserializeObject(jsonContent);

            log.Info(jsonContent);

            if (data.assetId == null)
            {
                // for test
                // data.assetId = "nb:cid:UUID:d9496372-32f5-430d-a4c6-d21ec3e01525";

                return(req.CreateResponse(HttpStatusCode.BadRequest, new
                {
                    error = "Please pass asset ID in the input object (assetId)"
                }));
            }

            if (data.document == null)
            {
                // for test
                // data.assetId = "nb:cid:UUID:d9496372-32f5-430d-a4c6-d21ec3e01525";

                return(req.CreateResponse(HttpStatusCode.BadRequest, new
                {
                    error = "Please pass document data in the input object (document)"
                }));
            }


            if (data.fileName == null)
            {
                // for test
                // data.assetId = "nb:cid:UUID:d9496372-32f5-430d-a4c6-d21ec3e01525";

                return(req.CreateResponse(HttpStatusCode.BadRequest, new
                {
                    error = "Please pass the file name data in the input object (fileName)"
                }));
            }

            MediaServicesCredentials amsCredentials = new MediaServicesCredentials();

            log.Info($"Using Azure Media Service Rest API Endpoint : {amsCredentials.AmsRestApiEndpoint}");


            try
            {
                string document = (string)data.document;
                string fileName = (string)data.fileName;

                AzureAdTokenCredentials tokenCredentials = new AzureAdTokenCredentials(amsCredentials.AmsAadTenantDomain,
                                                                                       new AzureAdClientSymmetricKey(amsCredentials.AmsClientId, amsCredentials.AmsClientSecret),
                                                                                       AzureEnvironments.AzureCloudEnvironment);

                AzureAdTokenProvider tokenProvider = new AzureAdTokenProvider(tokenCredentials);

                _context = new CloudMediaContext(amsCredentials.AmsRestApiEndpoint, tokenProvider);

                // Get the asset
                string assetid   = data.assetId;
                var    destAsset = _context.Assets.Where(a => a.Id == assetid).FirstOrDefault();

                if (destAsset == null)
                {
                    log.Info($"Asset not found {assetid}");
                    return(req.CreateResponse(HttpStatusCode.BadRequest, new
                    {
                        error = "Asset not found"
                    }));
                }

                log.Info(@"creation of file {fileName}");

                var filetocreate = destAsset.AssetFiles.Create(fileName);

                using (Stream s = GenerateStreamFromString(document))
                {
                    filetocreate.Upload(s);
                }

                if (data.convertTtml != null && ((bool)data.convertTtml == true))
                { // let's convert the ttml to vtt
                    log.Info("ttml to vtt convert process...");
                    XNamespace    xmlns     = "http://www.w3.org/ns/ttml";
                    XDocument     docXML    = XDocument.Parse(document);
                    var           tt        = docXML.Element(xmlns + "tt");
                    var           subtitles = docXML.Element(xmlns + "tt").Element(xmlns + "body").Element(xmlns + "div").Elements(xmlns + "p");
                    StringBuilder sbuild    = new StringBuilder();
                    string        vttarrow  = " --> ";
                    sbuild.AppendLine("WEBVTT");
                    sbuild.AppendLine();
                    foreach (var sub in subtitles)
                    {
                        var begin = (string)sub.Attribute("begin");
                        var end   = (string)sub.Attribute("end");
                        var text  = (string)sub.Value;
                        sbuild.AppendLine(begin + vttarrow + end);
                        sbuild.AppendLine(text);
                        sbuild.AppendLine();
                    }

                    string vttfilename = Path.GetFileNameWithoutExtension(fileName) + ".vtt";
                    log.Info(@"creation of file {vttfilename}");
                    var filetocreate2 = destAsset.AssetFiles.Create(vttfilename);
                    using (Stream s2 = GenerateStreamFromString(sbuild.ToString()))
                    {
                        filetocreate2.Upload(s2);
                    }
                }
            }
            catch (Exception ex)
            {
                string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : "");
                log.Info($"ERROR: Exception {message}");
                return(req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message }));
            }

            log.Info($"");
            return(req.CreateResponse(HttpStatusCode.OK));
        }
        public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log)

        {
            log.Info($"Webhook was triggered!");

            string jsonContent = await req.Content.ReadAsStringAsync();

            dynamic data = JsonConvert.DeserializeObject(jsonContent);

            log.Info(jsonContent);

            if (data.channelName == null)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new
                {
                    error = "Please pass channelName in the input object"
                }));
            }
            if (data.programName == null)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new
                {
                    error = "Please pass programName in the input object"
                }));
            }
            string   channelName   = data.channelName;
            string   programName   = data.programName;
            string   assetName     = data.assetName;
            IProgram program       = null;
            TimeSpan archiveLength = new TimeSpan(0, data.archiveWindowLength != null ? (int)data.archiveWindowLength : 5, 0); // default 5 min

            MediaServicesCredentials amsCredentials = new MediaServicesCredentials();

            log.Info($"Using Azure Media Service Rest API Endpoint : {amsCredentials.AmsRestApiEndpoint}");

            IAsset newAsset = null;

            try
            {
                AzureAdTokenCredentials tokenCredentials = new AzureAdTokenCredentials(amsCredentials.AmsAadTenantDomain,
                                                                                       new AzureAdClientSymmetricKey(amsCredentials.AmsClientId, amsCredentials.AmsClientSecret),
                                                                                       AzureEnvironments.AzureCloudEnvironment);

                AzureAdTokenProvider tokenProvider = new AzureAdTokenProvider(tokenCredentials);

                _context = new CloudMediaContext(amsCredentials.AmsRestApiEndpoint, tokenProvider);

                log.Info("Context object created.");

                var channel = _context.Channels.Where(c => c.Name == channelName).FirstOrDefault();
                if (channel == null)
                {
                    return(req.CreateResponse(HttpStatusCode.BadRequest, new
                    {
                        error = string.Format("Channel {0} not found", channelName)
                    }));
                }

                newAsset = _context.Assets.Create(assetName, (string)data.assetStorage, AssetCreationOptions.None);

                log.Info("new asset created.");

                if (data.alternateId != null)
                {
                    newAsset.AlternateId = (string)data.alternateId;
                    newAsset.Update();
                }


                ProgramCreationOptions options = new ProgramCreationOptions()
                {
                    Name                = programName,
                    ManifestName        = data.manifestName,
                    Description         = data.description,
                    AssetId             = newAsset.Id,
                    ArchiveWindowLength = archiveLength
                };
                program = channel.Programs.Create(options);

                log.Info("new program created.");


                if (data.startProgram == null || (data.startProgram != null && (bool)data.startProgram))
                {
                    log.Info("starting program...");
                    program.Start();
                    log.Info("Program started.");
                }

                program = _context.Programs.Where(p => p.Id == program.Id).FirstOrDefault(); // refresh
            }
            catch (Exception ex)
            {
                string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : "");
                log.Info($"ERROR: Exception {message}");
                return(req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message }));
            }

            log.Info("asset Id: " + newAsset.Id);
            log.Info("container Path: " + newAsset.Uri.Segments[1]);

            return(req.CreateResponse(HttpStatusCode.OK, new
            {
                containerPath = newAsset.Uri.Segments[1],
                assetId = newAsset.Id,
                manifestName = program.ManifestName,
                id = program.Id,
                state = program.State
            }));
        }
示例#19
0
        public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log, Microsoft.Azure.WebJobs.ExecutionContext execContext)
        {
            log.Info($"Webhook was triggered!");

            // Init variables

            string jsonContent = await req.Content.ReadAsStringAsync();

            dynamic data = JsonConvert.DeserializeObject(jsonContent);

            string fileName     = null;
            var    manifestInfo = new ManifestHelpers.ManifestGenerated();

            log.Info(jsonContent);

            if (data.assetId == null)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new
                {
                    error = "Please pass asset ID in the input object (assetId)"
                }));
            }

            MediaServicesCredentials amsCredentials = new MediaServicesCredentials();

            log.Info($"Using Azure Media Service Rest API Endpoint : {amsCredentials.AmsRestApiEndpoint}");

            bool checkStreamingEndpointResponse        = false;
            bool checkStreamingEndpointResponseSuccess = true;

            try
            {
                fileName = (string)data.fileName;

                AzureAdTokenCredentials tokenCredentials = new AzureAdTokenCredentials(amsCredentials.AmsAadTenantDomain,
                                                                                       new AzureAdClientSymmetricKey(amsCredentials.AmsClientId, amsCredentials.AmsClientSecret),
                                                                                       AzureEnvironments.AzureCloudEnvironment);

                AzureAdTokenProvider tokenProvider = new AzureAdTokenProvider(tokenCredentials);

                _context = new CloudMediaContext(amsCredentials.AmsRestApiEndpoint, tokenProvider);

                // Get the asset
                string assetid   = data.assetId;
                var    destAsset = _context.Assets.Where(a => a.Id == assetid).FirstOrDefault();

                if (destAsset == null)
                {
                    log.Info($"Asset not found {assetid}");
                    return(req.CreateResponse(HttpStatusCode.BadRequest, new
                    {
                        error = "Asset not found"
                    }));
                }

                log.Info($"creation of file {fileName}");

                // Manifest generate
                manifestInfo = ManifestHelpers.LoadAndUpdateManifestTemplate(destAsset, execContext);

                // if not file name passed, then we use the one generated based on mp4 files names
                if (fileName == null)
                {
                    fileName = manifestInfo.FileName;
                }

                var filetocreate = destAsset.AssetFiles.Create(fileName);

                using (Stream s = ManifestHelpers.GenerateStreamFromString(manifestInfo.Content))
                {
                    filetocreate.Upload(s);
                }

                log.Info("Manifest file created.");

                // let's make the manifest the primary file of the asset
                MediaServicesHelper.SetFileAsPrimary(destAsset, fileName);
                log.Info("Manifest file set as primary.");



                if (data.checkStreamingEndpointResponse != null && (bool)data.checkStreamingEndpointResponse)
                {
                    checkStreamingEndpointResponse = true;
                    // testing streaming
                    // publish with a streaming locator (1 hour)
                    IAccessPolicy readPolicy       = _context.AccessPolicies.Create("readPolicy", TimeSpan.FromHours(1), AccessPermissions.Read);
                    ILocator      outputLocator    = _context.Locators.CreateLocator(LocatorType.OnDemandOrigin, destAsset, readPolicy);
                    var           publishurlsmooth = MediaServicesHelper.GetValidOnDemandURI(_context, destAsset);

                    try
                    {
                        WebRequest  request  = WebRequest.Create(publishurlsmooth.ToString());
                        WebResponse response = request.GetResponse();
                        response.Close();
                    }

                    catch (Exception ex)
                    {
                        checkStreamingEndpointResponseSuccess = false;
                    }
                    outputLocator.Delete();
                    readPolicy.Delete();
                }
            }
            catch (Exception ex)
            {
                string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : "");
                log.Info($"ERROR: Exception {message}");
                return(req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message }));
            }

            log.Info($"");

            if (checkStreamingEndpointResponse)
            {
                return(req.CreateResponse(HttpStatusCode.OK, new
                {
                    fileName = fileName,
                    manifestContent = manifestInfo.Content,
                    checkStreamingEndpointResponseSuccess = checkStreamingEndpointResponseSuccess
                }));
            }
            else
            {
                return(req.CreateResponse(HttpStatusCode.OK, new
                {
                    fileName = fileName,
                    manifestContent = manifestInfo.Content
                }));
            }
        }
示例#20
0
        public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log)
        {
            log.Info($"AMS v2 Function - Add Asset Delivery Policy was triggered!");

            string jsonContent = await req.Content.ReadAsStringAsync();

            if (string.IsNullOrEmpty(jsonContent))
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass a JSON request body" }));
            }

            object data = JsonConvert.DeserializeObject(jsonContent);

            string hexIv = GetHexIV();

            IAssetDeliveryPolicy result;
            IContentKey          contentKey;

            try
            {
                result = CreateFairplayAssetDeliveryPolicy(hexIv, out contentKey);
            }
            catch (Exception ex)
            {
                string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : "") + "\n" + ex.StackTrace;
                log.Info($"ERROR: Exception {message}");
                return(req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message }));
            }

            return(req.CreateResponse(HttpStatusCode.OK, new
            {
                assetDeliveryPolicyId = result.Id,
                contentKeyId = contentKey.Id,
                hexIv = hexIv,
            }));
        }
示例#21
0
        public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log)

        {
            log.Info($"Webhook was triggered!");

            string jsonContent = await req.Content.ReadAsStringAsync();

            dynamic data = JsonConvert.DeserializeObject(jsonContent);

            log.Info(jsonContent);

            if (data.assetName == null)
            {
                // for test
                // data.Path = "/input/WP_20121015_081924Z.mp4";

                return(req.CreateResponse(HttpStatusCode.BadRequest, new
                {
                    error = "Please pass assetName in the input object"
                }));
            }

            string assetName = data.assetName;

            MediaServicesCredentials amsCredentials = new MediaServicesCredentials();

            log.Info($"Using Azure Media Service Rest API Endpoint : {amsCredentials.AmsRestApiEndpoint}");

            IAsset newAsset = null;

            try
            {
                AzureAdTokenCredentials tokenCredentials = new AzureAdTokenCredentials(amsCredentials.AmsAadTenantDomain,
                                                                                       new AzureAdClientSymmetricKey(amsCredentials.AmsClientId, amsCredentials.AmsClientSecret),
                                                                                       AzureEnvironments.AzureCloudEnvironment);

                AzureAdTokenProvider tokenProvider = new AzureAdTokenProvider(tokenCredentials);

                _context = new CloudMediaContext(amsCredentials.AmsRestApiEndpoint, tokenProvider);

                log.Info("Context object created.");

                newAsset = _context.Assets.Create(assetName, (string)data.assetStorage, AssetCreationOptions.None);

                log.Info("new asset created.");

                if (data.alternateId != null)
                {
                    newAsset.AlternateId = (string)data.alternateId;
                    newAsset.Update();
                }
            }
            catch (Exception ex)
            {
                string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : "");
                log.Info($"ERROR: Exception {message}");
                return(req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message }));
            }


            log.Info("asset Id: " + newAsset.Id);
            log.Info("container Path: " + newAsset.Uri.Segments[1]);

            return(req.CreateResponse(HttpStatusCode.OK, new
            {
                containerPath = newAsset.Uri.Segments[1],
                assetId = newAsset.Id
            }));
        }
        public static async Task<object> Run([HttpTrigger(WebHookType = "genericJson")]HttpRequestMessage req, TraceWriter log)
        {
            log.Info($"Webhook was triggered!");

            string jsonContent = await req.Content.ReadAsStringAsync();
            dynamic data = JsonConvert.DeserializeObject(jsonContent);
            log.Info("Request : " + jsonContent);

            MediaServicesCredentials amsCredentials = new MediaServicesCredentials();

            var attachedstoragecred = KeyHelper.ReturnStorageCredentials();

            // Validate input objects
            int delay = 5000;
            if (data.destinationContainer == null)
                return req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass DestinationContainer in the input object" });
            if (data.delay != null)
                delay = data.delay;
            log.Info("Input - DestinationContainer : " + data.destinationContainer);
            //log.Info("delay : " + delay);

            log.Info($"Wait " + delay + "(ms)");
            System.Threading.Thread.Sleep(delay);


            string storname = amsCredentials.StorageAccountName;
            string storkey = amsCredentials.StorageAccountKey;
            if (data.assetStorage != null)
            {
                string assetstor = (string)data.assetStorage;
                if (assetstor != amsCredentials.StorageAccountName)
                {
                    if (attachedstoragecred.ContainsKey(assetstor)) // asset is using another storage than default but we have the key
                    {
                        storname = assetstor;
                        storkey = attachedstoragecred[storname];
                    }
                    else // we don't have the key for that storage
                    {
                        log.Info($"Face redaction Asset is in {assetstor} and key is not provided in MediaServicesAttachedStorageCredentials application settings");
                        return req.CreateResponse(HttpStatusCode.BadRequest, new
                        {
                            error = "Storage key is missing"
                        });
                    }
                }
            }

            string destinationContainerName = data.destinationContainer;
            CloudBlobContainer destinationBlobContainer = CopyBlobHelpers.GetCloudBlobContainer(storname, storkey, destinationContainerName);

            CopyStatus copyStatus = CopyStatus.Success;
            try
            {
                string blobPrefix = null;
                bool useFlatBlobListing = true;
                var destBlobList = destinationBlobContainer.ListBlobs(blobPrefix, useFlatBlobListing, BlobListingDetails.Copy);
                foreach (var dest in destBlobList)
                {
                    var destBlob = dest as CloudBlob;
                    if (destBlob.CopyState.Status == CopyStatus.Aborted || destBlob.CopyState.Status == CopyStatus.Failed)
                    {
                        // Log the copy status description for diagnostics and restart copy
                        destBlob.StartCopyAsync(destBlob.CopyState.Source);
                        copyStatus = CopyStatus.Pending;
                    }
                    else if (destBlob.CopyState.Status == CopyStatus.Pending)
                    {
                        // We need to continue waiting for this pending copy
                        // However, let us log copy state for diagnostics
                        copyStatus = CopyStatus.Pending;
                    }
                    // else we completed this pending copy
                }
            }
            catch (Exception ex)
            {
                string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : "");
                log.Info($"ERROR: Exception {message}");
                return req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message });
            }

            return req.CreateResponse(HttpStatusCode.OK, new
            {
                copyStatus = copyStatus,
                isRunning = (copyStatus == CopyStatus.Pending).ToString(),
                isSuccessful = (copyStatus == CopyStatus.Success).ToString()
            });
        }
示例#23
0
        public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log)
        {
            {
                log.Info($"Webhook was triggered!");

                // Init variables
                string  pathUrl            = "";
                dynamic pngThumbnails      = new JArray() as dynamic;
                string  prefixpng          = "";
                string  copyToContainer    = "";
                string  targetContainerUri = "";

                TimeSpan timeOffset = new TimeSpan(0);

                string jsonContent = await req.Content.ReadAsStringAsync();

                dynamic data = JsonConvert.DeserializeObject(jsonContent);

                var attachedstoragecred = KeyHelper.ReturnStorageCredentials();

                log.Info(jsonContent);

                MediaServicesCredentials amsCredentials = new MediaServicesCredentials();
                log.Info($"Using Azure Media Service Rest API Endpoint : {amsCredentials.AmsRestApiEndpoint}");

                try
                {
                    AzureAdTokenCredentials tokenCredentials = new AzureAdTokenCredentials(amsCredentials.AmsAadTenantDomain,
                                                                                           new AzureAdClientSymmetricKey(amsCredentials.AmsClientId, amsCredentials.AmsClientSecret),
                                                                                           AzureEnvironments.AzureCloudEnvironment);

                    AzureAdTokenProvider tokenProvider = new AzureAdTokenProvider(tokenCredentials);

                    _context = new CloudMediaContext(amsCredentials.AmsRestApiEndpoint, tokenProvider);


                    //
                    // MES Thumbnails
                    //
                    if (data.mesThumbnails != null && data.mesThumbnails.assetId != null)
                    {
                        List <CloudBlob> listPNGCopies = new List <CloudBlob>();

                        // Get the asset
                        string assetid     = data.mesThumbnails.assetId;
                        var    outputAsset = _context.Assets.Where(a => a.Id == assetid).FirstOrDefault();

                        if (outputAsset == null)
                        {
                            log.Info($"Asset not found {assetid}");
                            return(req.CreateResponse(HttpStatusCode.BadRequest, new
                            {
                                error = "Asset not found"
                            }));
                        }

                        var pngFiles = outputAsset.AssetFiles.Where(a => a.Name.ToUpper().EndsWith(".PNG"));

                        Uri publishurl = MediaServicesHelper.GetValidOnDemandPath(_context, outputAsset);
                        if (publishurl != null)
                        {
                            pathUrl = publishurl.ToString();
                        }
                        else
                        {
                            log.Info($"Asset not published");
                        }

                        // Let's copy the PNG Thumbnails
                        if (data.mesThumbnails.copyToContainer != null)
                        {
                            copyToContainer = data.mesThumbnails.copyToContainer + DateTime.UtcNow.ToString("yyyyMMdd");
                            // let's copy PNG to a container
                            prefixpng = outputAsset.Uri.Segments[1] + "-";
                            log.Info($"prefixpng {prefixpng}");

                            string storname = amsCredentials.StorageAccountName;
                            string storkey  = amsCredentials.StorageAccountKey;
                            if (outputAsset.StorageAccountName != amsCredentials.StorageAccountName)
                            {
                                if (attachedstoragecred.ContainsKey(outputAsset.StorageAccountName)) // asset is using another storage than default but we have the key
                                {
                                    storname = outputAsset.StorageAccountName;
                                    storkey  = attachedstoragecred[storname];
                                }
                                else // we don't have the key for that storage
                                {
                                    log.Info($"MES Thumbnails Asset is in {outputAsset.StorageAccountName} and key is not provided in MediaServicesAttachedStorageCredentials application settings");
                                    return(req.CreateResponse(HttpStatusCode.BadRequest, new
                                    {
                                        error = "Storage key is missing"
                                    }));
                                }
                            }

                            var sourceContainer = CopyBlobHelpers.GetCloudBlobContainer(storname, storkey, outputAsset.Uri.Segments[1]);

                            CloudBlobContainer targetContainer;
                            if (data.mesThumbnails.copyToContainerAccountName != null)
                            {
                                // copy to a specific storage account
                                targetContainer = CopyBlobHelpers.GetCloudBlobContainer((string)data.mesThumbnails.copyToContainerAccountName, (string)data.mesThumbnails.copyToContainerAccountKey, copyToContainer);
                            }
                            else
                            {
                                // copy to ams storage account
                                targetContainer = CopyBlobHelpers.GetCloudBlobContainer(amsCredentials.StorageAccountName, amsCredentials.StorageAccountKey, copyToContainer);
                            }

                            listPNGCopies = await CopyBlobHelpers.CopyFilesAsync(sourceContainer, targetContainer, prefixpng, "png", log);

                            targetContainerUri = targetContainer.Uri.ToString();
                        }

                        foreach (IAssetFile file in pngFiles)
                        {
                            string index   = file.Name.Substring(file.Name.Length - 10, 6);
                            int    index_i = 0;
                            if (int.TryParse(index, out index_i))
                            {
                                dynamic entry = new JObject();
                                entry.id       = index_i;
                                entry.fileId   = file.Id;
                                entry.fileName = file.Name;
                                if (copyToContainer != "")
                                {
                                    entry.url = targetContainerUri + "/" + prefixpng + file.Name;
                                }
                                else if (!string.IsNullOrEmpty(pathUrl))
                                {
                                    entry.url = pathUrl + file.Name;
                                }
                                pngThumbnails.Add(entry);
                            }
                        }

                        if (data.mesThumbnails.deleteAsset != null && ((bool)data.mesThumbnails.deleteAsset))
                        {
                            // If asset deletion was asked
                            // let's wait for the copy to finish before deleting the asset..
                            if (listPNGCopies.Count > 0)
                            {
                                log.Info("PNG Copy with asset deletion was asked. Checking copy status...");
                                bool continueLoop = true;
                                while (continueLoop)
                                {
                                    listPNGCopies = listPNGCopies.Where(r => r.CopyState.Status == CopyStatus.Pending).ToList();
                                    if (listPNGCopies.Count == 0)
                                    {
                                        continueLoop = false;
                                    }
                                    else
                                    {
                                        log.Info("PNG Copy not finished. Waiting 3s...");
                                        Task.Delay(TimeSpan.FromSeconds(3d)).Wait();
                                        listPNGCopies.ForEach(r => r.FetchAttributes());
                                    }
                                }
                            }
                            outputAsset.Delete();
                        }
                    }
                }
                catch (Exception ex)
                {
                    string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : "");
                    log.Info($"ERROR: Exception {message}");
                    return(req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message }));
                }

                log.Info($"");
                return(req.CreateResponse(HttpStatusCode.OK, new
                {
                    mesThumbnail = new
                    {
                        pngThumbnails = Newtonsoft.Json.JsonConvert.SerializeObject(pngThumbnails)
                    }
                }));
            }
        }
        public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log)
        {
            log.Info($"Webhook was triggered!");

            string jsonContent = await req.Content.ReadAsStringAsync();

            dynamic data = JsonConvert.DeserializeObject(jsonContent);

            log.Info(jsonContent);

            if (data.jobId == null || data.taskId == null)
            {
                // used to test the function
                //data.jobId = "nb:jid:UUID:acf38b8a-aef9-4789-9f0f-f69bf6ccb8e5";
                return(req.CreateResponse(HttpStatusCode.BadRequest, new
                {
                    error = "Please pass the job and task ID in the input object (jobId, taskId)"
                }));
            }

            MediaServicesCredentials amsCredentials = new MediaServicesCredentials();

            log.Info($"Using Azure Media Service Rest API Endpoint : {amsCredentials.AmsRestApiEndpoint}");

            IJob          job             = null;
            ITask         task            = null;
            string        startTime       = "";
            string        endTime         = "";
            StringBuilder sberror         = new StringBuilder();
            string        runningDuration = "";
            bool          isRunning       = true;
            bool          isSuccessful    = true;

            bool extendedInfo = false;

            if (data.extendedInfo != null && ((bool)data.extendedInfo) == true)
            {
                extendedInfo = true;
            }

            try
            {
                AzureAdTokenCredentials tokenCredentials = new AzureAdTokenCredentials(amsCredentials.AmsAadTenantDomain,
                                                                                       new AzureAdClientSymmetricKey(amsCredentials.AmsClientId, amsCredentials.AmsClientSecret),
                                                                                       AzureEnvironments.AzureCloudEnvironment);

                AzureAdTokenProvider tokenProvider = new AzureAdTokenProvider(tokenCredentials);

                _context = new CloudMediaContext(amsCredentials.AmsRestApiEndpoint, tokenProvider);

                // Get the job
                string jobid = (string)data.jobId;
                job = _context.Jobs.Where(j => j.Id == jobid).FirstOrDefault();

                if (job == null)
                {
                    log.Info($"Job not found {jobid}");

                    return(req.CreateResponse(HttpStatusCode.InternalServerError, new
                    {
                        error = "Job not found"
                    }));
                }

                // Get the task
                string taskid = (string)data.taskId;
                task = job.Tasks.Where(j => j.Id == taskid).FirstOrDefault();

                if (task == null)
                {
                    log.Info($"Task not found {taskid}");

                    return(req.CreateResponse(HttpStatusCode.InternalServerError, new
                    {
                        error = "Task not found"
                    }));
                }

                if (data.noWait != null && (bool)data.noWait)
                {
                    // No wait
                }
                else
                {
                    for (int i = 1; i <= 3; i++) // let's wait 3 times 5 seconds (15 seconds)
                    {
                        log.Info($"Task {task.Id} status is {task.State}");

                        if (task.State == JobState.Finished || task.State == JobState.Canceled || task.State == JobState.Error)
                        {
                            break;
                        }

                        log.Info("Waiting 5 s...");
                        System.Threading.Thread.Sleep(5 * 1000);
                        task = job.Tasks.Where(j => j.Id == taskid).FirstOrDefault();
                    }
                }

                if (task.State == JobState.Error || task.State == JobState.Canceled)
                {
                    foreach (var details in task.ErrorDetails)
                    {
                        sberror.AppendLine(task.Name + " : " + details.Message);
                    }
                }

                if (task.StartTime != null)
                {
                    startTime = ((DateTime)task.StartTime).ToString("o");
                }

                if (task.EndTime != null)
                {
                    endTime = ((DateTime)task.EndTime).ToString("o");
                }

                if (task.RunningDuration != null)
                {
                    runningDuration = task.RunningDuration.ToString();
                }
            }
            catch (Exception ex)
            {
                string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : "");
                log.Info($"ERROR: Exception {message}");
                return(req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message }));
            }

            isRunning    = !(task.State == JobState.Finished || task.State == JobState.Canceled || task.State == JobState.Error);
            isSuccessful = (task.State == JobState.Finished);

            if (extendedInfo && (task.State == JobState.Finished || task.State == JobState.Canceled || task.State == JobState.Error))
            {
                dynamic stats = new JObject();
                stats.mediaUnitNumber     = _context.EncodingReservedUnits.FirstOrDefault().CurrentReservedUnits;
                stats.mediaUnitSize       = MediaServicesHelper.ReturnMediaReservedUnitName(_context.EncodingReservedUnits.FirstOrDefault().ReservedUnitType);;
                stats.otherJobsProcessing = _context.Jobs.Where(j => j.State == JobState.Processing).Count();
                stats.otherJobsScheduled  = _context.Jobs.Where(j => j.State == JobState.Scheduled).Count();
                stats.otherJobsQueue      = _context.Jobs.Where(j => j.State == JobState.Queued).Count();
                stats.amsRESTAPIEndpoint  = amsCredentials.AmsRestApiEndpoint;

                return(req.CreateResponse(HttpStatusCode.OK, new
                {
                    taskState = task.State,
                    errorText = sberror.ToString(),
                    startTime = startTime,
                    endTime = endTime,
                    runningDuration = runningDuration,
                    extendedInfo = stats.ToString(),
                    isRunning = isRunning.ToString(),
                    isSuccessful = isSuccessful.ToString(),
                    progress = task.Progress
                }));
            }
            else
            {
                return(req.CreateResponse(HttpStatusCode.OK, new
                {
                    taskState = task.State,
                    errorText = sberror.ToString(),
                    startTime = startTime,
                    endTime = endTime,
                    runningDuration = runningDuration,
                    isRunning = isRunning.ToString(),
                    isSuccessful = isSuccessful.ToString(),
                    progress = task.Progress
                }));
            }
        }
示例#25
0
        public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log, Microsoft.Azure.WebJobs.ExecutionContext execContext)
        {
            int    taskindex = 0;
            bool   useEncoderOutputForAnalytics = false;
            IAsset outputEncoding = null;

            log.Info($"Webhook was triggered!");
            string triggerStart = DateTime.UtcNow.ToString("o");

            string jsonContent = await req.Content.ReadAsStringAsync();

            dynamic data = JsonConvert.DeserializeObject(jsonContent);

            log.Info(jsonContent);

            log.Info($"asset id : {data.assetId}");

            if (data.assetId == null)
            {
                // for test
                // data.assetId = "nb:cid:UUID:2d0d78a2-685a-4b14-9cf0-9afb0bb5dbfc";

                return(req.CreateResponse(HttpStatusCode.BadRequest, new
                {
                    error = "Please pass asset ID in the input object (assetId)"
                }));
            }


            IJob  job          = null;
            ITask taskEncoding = null;

            int OutputMES             = -1;
            int OutputMEPW            = -1;
            int OutputIndex1          = -1;
            int OutputIndex2          = -1;
            int OutputOCR             = -1;
            int OutputFaceDetection   = -1;
            int OutputMotion          = -1;
            int OutputSummarization   = -1;
            int OutputFaceRedaction   = -1;
            int OutputMesThumbnails   = -1;
            int OutputVideoAnnotation = -1;
            int NumberJobsQueue       = 0;

            MediaServicesCredentials amsCredentials = new MediaServicesCredentials();

            log.Info($"Using Azure Media Service Rest API Endpoint : {amsCredentials.AmsRestApiEndpoint}");

            try
            {
                AzureAdTokenCredentials tokenCredentials = new AzureAdTokenCredentials(amsCredentials.AmsAadTenantDomain,
                                                                                       new AzureAdClientSymmetricKey(amsCredentials.AmsClientId, amsCredentials.AmsClientSecret),
                                                                                       AzureEnvironments.AzureCloudEnvironment);

                AzureAdTokenProvider tokenProvider = new AzureAdTokenProvider(tokenCredentials);

                _context = new CloudMediaContext(amsCredentials.AmsRestApiEndpoint, tokenProvider);


                // find the Asset
                string assetid = (string)data.assetId;
                IAsset asset   = _context.Assets.Where(a => a.Id == assetid).FirstOrDefault();

                if (asset == null)
                {
                    log.Info($"Asset not found {assetid}");
                    return(req.CreateResponse(HttpStatusCode.BadRequest, new
                    {
                        error = "Asset not found"
                    }));
                }

                if (data.useEncoderOutputForAnalytics != null && ((bool)data.useEncoderOutputForAnalytics) && (data.mesPreset != null || data.mes != null))  // User wants to use encoder output for media analytics
                {
                    useEncoderOutputForAnalytics = (bool)data.useEncoderOutputForAnalytics;
                }


                // Declare a new encoding job with the Standard encoder
                int priority = 10;
                if (data.priority != null)
                {
                    priority = (int)data.priority;
                }
                job = _context.Jobs.Create(((string)data.jobName) ?? "Azure Functions Job", priority);

                if (data.mes != null || data.mesPreset != null)  // MES Task
                {
                    // Get a media processor reference, and pass to it the name of the
                    // processor to use for the specific task.
                    IMediaProcessor processorMES = MediaServicesHelper.GetLatestMediaProcessorByName(_context, "Media Encoder Standard");

                    string preset = null;
                    if (data.mes != null)
                    {
                        preset = (string)data.mes.preset;
                    }
                    else
                    {
                        preset = (string)data.mesPreset; // Compatibility mode
                    }
                    if (preset == null)
                    {
                        preset = "Content Adaptive Multiple Bitrate MP4";  // the default preset
                    }

                    if (preset.ToUpper().EndsWith(".JSON"))
                    {
                        // Build the folder path to the preset
                        string presetPath = Path.Combine(System.IO.Directory.GetParent(execContext.FunctionDirectory).FullName, "presets", preset);
                        log.Info("presetPath= " + presetPath);
                        preset = File.ReadAllText(presetPath);
                    }

                    // Create a task with the encoding details, using a string preset.
                    // In this case "H264 Multiple Bitrate 720p" system defined preset is used.
                    taskEncoding = job.Tasks.AddNew("MES encoding task",
                                                    processorMES,
                                                    preset,
                                                    TaskOptions.None);

                    // Specify the input asset to be encoded.
                    taskEncoding.InputAssets.Add(asset);
                    OutputMES = taskindex++;

                    // Add an output asset to contain the results of the job.
                    // This output is specified as AssetCreationOptions.None, which
                    // means the output asset is not encrypted.
                    outputEncoding = taskEncoding.OutputAssets.AddNew(asset.Name + " MES encoded", JobHelpers.OutputStorageFromParam(data.mes), AssetCreationOptions.None);
                }

                if (data.mepw != null || data.workflowAssetId != null) // Premium Encoder Task
                {
                    //find the workflow asset
                    string workflowassetid = null;
                    if (data.mepw != null)
                    {
                        workflowassetid = (string)data.mepw.workflowAssetId;
                    }
                    else
                    {
                        workflowassetid = (string)data.workflowAssetId; // compatibility mode
                    }

                    IAsset workflowAsset = _context.Assets.Where(a => a.Id == workflowassetid).FirstOrDefault();

                    if (workflowAsset == null)
                    {
                        log.Info($"Workflow not found {workflowassetid}");
                        return(req.CreateResponse(HttpStatusCode.BadRequest, new
                        {
                            error = "Workflow not found"
                        }));
                    }

                    // Get a media processor reference, and pass to it the name of the
                    // processor to use for the specific task.
                    IMediaProcessor processorMEPW = MediaServicesHelper.GetLatestMediaProcessorByName(_context, "Media Encoder Premium Workflow");

                    string premiumConfiguration = "";
                    if (data.mepw != null && data.mepw.workflowConfig != null)
                    {
                        premiumConfiguration = (string)data.mepw.workflowConfig;
                    }
                    else if (data.workflowConfig != null)
                    {
                        premiumConfiguration = (string)data.workflowConfig; // compatibility mode
                    }

                    // In some cases, a configuration can be loaded and passed it to the task to tuned the workflow
                    // premiumConfiguration=File.ReadAllText(Path.Combine(System.IO.Directory.GetParent(execContext.FunctionDirectory).FullName, "presets", "SetRuntime.xml")).Replace("VideoFileName", VideoFile.Name).Replace("AudioFileName", AudioFile.Name);

                    // Create a task
                    taskEncoding = job.Tasks.AddNew("Premium Workflow encoding task",
                                                    processorMEPW,
                                                    premiumConfiguration,
                                                    TaskOptions.None);

                    log.Info("task created");

                    // Specify the input asset to be encoded.
                    taskEncoding.InputAssets.Add(workflowAsset); // first add the Workflow
                    taskEncoding.InputAssets.Add(asset);         // Then add the video asset
                    OutputMEPW = taskindex++;

                    // Add an output asset to contain the results of the job.
                    // This output is specified as AssetCreationOptions.None, which
                    // means the output asset is not encrypted.
                    outputEncoding = taskEncoding.OutputAssets.AddNew(asset.Name + " Premium encoded", JobHelpers.OutputStorageFromParam(data.mepw), AssetCreationOptions.None);
                }

                IAsset an_asset = useEncoderOutputForAnalytics ? outputEncoding : asset;

                // Media Analytics
                OutputIndex1          = JobHelpers.AddTask(execContext, _context, job, an_asset, (data.indexV1 == null) ? (string)data.indexV1Language : ((string)data.indexV1.language ?? "English"), "Azure Media Indexer", "IndexerV1.xml", "English", ref taskindex, specifiedStorageAccountName: JobHelpers.OutputStorageFromParam(data.indexV1));
                OutputIndex2          = JobHelpers.AddTask(execContext, _context, job, an_asset, (data.indexV2 == null) ? (string)data.indexV2Language : ((string)data.indexV2.language ?? "EnUs"), "Azure Media Indexer 2 Preview", "IndexerV2.json", "EnUs", ref taskindex, specifiedStorageAccountName: JobHelpers.OutputStorageFromParam(data.indexV2));
                OutputOCR             = JobHelpers.AddTask(execContext, _context, job, an_asset, (data.ocr == null) ? (string)data.ocrLanguage : ((string)data.ocr.language ?? "AutoDetect"), "Azure Media OCR", "OCR.json", "AutoDetect", ref taskindex, specifiedStorageAccountName: JobHelpers.OutputStorageFromParam(data.ocr));
                OutputFaceDetection   = JobHelpers.AddTask(execContext, _context, job, an_asset, (data.faceDetection == null) ? (string)data.faceDetectionMode : ((string)data.faceDetection.mode ?? "PerFaceEmotion"), "Azure Media Face Detector", "FaceDetection.json", "PerFaceEmotion", ref taskindex, specifiedStorageAccountName: JobHelpers.OutputStorageFromParam(data.faceDetection));
                OutputFaceRedaction   = JobHelpers.AddTask(execContext, _context, job, an_asset, (data.faceRedaction == null) ? (string)data.faceRedactionMode : ((string)data.faceRedaction.mode ?? "comined"), "Azure Media Redactor", "FaceRedaction.json", "combined", ref taskindex, specifiedStorageAccountName: JobHelpers.OutputStorageFromParam(data.faceRedaction));
                OutputMotion          = JobHelpers.AddTask(execContext, _context, job, an_asset, (data.motionDetection == null) ? (string)data.motionDetectionLevel : ((string)data.motionDetection.level ?? "medium"), "Azure Media Motion Detector", "MotionDetection.json", "medium", ref taskindex, specifiedStorageAccountName: JobHelpers.OutputStorageFromParam(data.motionDetection));
                OutputSummarization   = JobHelpers.AddTask(execContext, _context, job, an_asset, (data.summarization == null) ? (string)data.summarizationDuration : ((string)data.summarization.duration ?? "0.0"), "Azure Media Video Thumbnails", "Summarization.json", "0.0", ref taskindex, specifiedStorageAccountName: JobHelpers.OutputStorageFromParam(data.summarization));
                OutputVideoAnnotation = JobHelpers.AddTask(execContext, _context, job, an_asset, (data.videoAnnotation != null) ? "1.0" : null, "Azure Media Video Annotator", "VideoAnnotation.json", "1.0", ref taskindex, specifiedStorageAccountName: JobHelpers.OutputStorageFromParam(data.videoAnnotation));

                // MES Thumbnails
                OutputMesThumbnails = JobHelpers.AddTask(execContext, _context, job, asset, (data.mesThumbnails != null) ? ((string)data.mesThumbnails.Start ?? "{Best}") : null, "Media Encoder Standard", "MesThumbnails.json", "{Best}", ref taskindex, specifiedStorageAccountName: JobHelpers.OutputStorageFromParam(data.mesThumbnails));

                job.Submit();
                log.Info("Job Submitted");
                NumberJobsQueue = _context.Jobs.Where(j => j.State == JobState.Queued).Count();
            }
            catch (Exception ex)
            {
                string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : "");
                log.Info($"ERROR: Exception {message}");
                return(req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message }));
            }

            job = _context.Jobs.Where(j => j.Id == job.Id).FirstOrDefault(); // Let's refresh the job

            log.Info("Job Id: " + job.Id);
            log.Info("OutputAssetMESId: " + JobHelpers.ReturnId(job, OutputMES));
            log.Info("OutputAssetMEPWId: " + JobHelpers.ReturnId(job, OutputMEPW));
            log.Info("OutputAssetIndexV1Id: " + JobHelpers.ReturnId(job, OutputIndex1));
            log.Info("OutputAssetIndexV2Id: " + JobHelpers.ReturnId(job, OutputIndex2));
            log.Info("OutputAssetOCRId: " + JobHelpers.ReturnId(job, OutputOCR));
            log.Info("OutputAssetFaceDetectionId: " + JobHelpers.ReturnId(job, OutputFaceDetection));
            log.Info("OutputAssetFaceRedactionId: " + JobHelpers.ReturnId(job, OutputFaceRedaction));
            log.Info("OutputAssetMotionDetectionId: " + JobHelpers.ReturnId(job, OutputMotion));
            log.Info("OutputAssetSummarizationId: " + JobHelpers.ReturnId(job, OutputSummarization));
            log.Info("OutputMesThumbnailsId: " + JobHelpers.ReturnId(job, OutputMesThumbnails));
            log.Info("OutputAssetVideoAnnotationId: " + JobHelpers.ReturnId(job, OutputVideoAnnotation));

            return(req.CreateResponse(HttpStatusCode.OK, new
            {
                jobId = job.Id,
                otherJobsQueue = NumberJobsQueue,
                mes = new
                {
                    assetId = JobHelpers.ReturnId(job, OutputMES),
                    taskId = JobHelpers.ReturnTaskId(job, OutputMES)
                },
                mepw = new
                {
                    assetId = JobHelpers.ReturnId(job, OutputMEPW),
                    taskId = JobHelpers.ReturnTaskId(job, OutputMEPW)
                },
                indexV1 = new
                {
                    assetId = JobHelpers.ReturnId(job, OutputIndex1),
                    taskId = JobHelpers.ReturnTaskId(job, OutputIndex1),
                    language = (string)data.indexV1Language
                },
                indexV2 = new
                {
                    assetId = JobHelpers.ReturnId(job, OutputIndex2),
                    taskId = JobHelpers.ReturnTaskId(job, OutputIndex2),
                    language = (string)data.indexV2Language
                },
                ocr = new
                {
                    assetId = JobHelpers.ReturnId(job, OutputOCR),
                    taskId = JobHelpers.ReturnTaskId(job, OutputOCR)
                },
                faceDetection = new
                {
                    assetId = JobHelpers.ReturnId(job, OutputFaceDetection),
                    taskId = JobHelpers.ReturnTaskId(job, OutputFaceDetection)
                },
                faceRedaction = new
                {
                    assetId = JobHelpers.ReturnId(job, OutputFaceRedaction),
                    taskId = JobHelpers.ReturnTaskId(job, OutputFaceRedaction)
                },
                motionDetection = new
                {
                    assetId = JobHelpers.ReturnId(job, OutputMotion),
                    taskId = JobHelpers.ReturnTaskId(job, OutputMotion)
                },
                summarization = new
                {
                    assetId = JobHelpers.ReturnId(job, OutputSummarization),
                    taskId = JobHelpers.ReturnTaskId(job, OutputSummarization)
                },
                mesThumbnails = new
                {
                    assetId = JobHelpers.ReturnId(job, OutputMesThumbnails),
                    taskId = JobHelpers.ReturnTaskId(job, OutputMesThumbnails)
                },
                videoAnnotation = new
                {
                    assetId = JobHelpers.ReturnId(job, OutputVideoAnnotation),
                    taskId = JobHelpers.ReturnTaskId(job, OutputVideoAnnotation)
                }
            }));
        }
        static public ManifestTimingData GetManifestTimingData(CloudMediaContext context, IAsset asset, TraceWriter log)
        // Parse the manifest and get data from it
        {
            ManifestTimingData response = new ManifestTimingData()
            {
                IsLive = false, Error = false, TimestampOffset = 0, TimestampList = new List <ulong>(), DiscontinuityDetected = false
            };

            try
            {
                ILocator mytemplocator = null;
                Uri      myuri         = MediaServicesHelper.GetValidOnDemandURI(context, asset);
                if (myuri == null)
                {
                    mytemplocator = MediaServicesHelper.CreatedTemporaryOnDemandLocator(asset);
                    myuri         = MediaServicesHelper.GetValidOnDemandURI(context, asset);
                }
                if (myuri != null)
                {
                    log.Info($"Asset URI {myuri.ToString()}");

                    XDocument manifest = XDocument.Load(myuri.ToString());

                    //log.Info($"manifest {manifest}");
                    var smoothmedia = manifest.Element("SmoothStreamingMedia");
                    var videotrack  = smoothmedia.Elements("StreamIndex").Where(a => a.Attribute("Type").Value == "video");

                    // TIMESCALE
                    string timescalefrommanifest = smoothmedia.Attribute("TimeScale").Value;
                    if (videotrack.FirstOrDefault().Attribute("TimeScale") != null) // there is timescale value in the video track. Let's take this one.
                    {
                        timescalefrommanifest = videotrack.FirstOrDefault().Attribute("TimeScale").Value;
                    }
                    ulong timescale = ulong.Parse(timescalefrommanifest);
                    response.TimeScale = (ulong?)timescale;

                    // Timestamp offset
                    if (videotrack.FirstOrDefault().Element("c").Attribute("t") != null)
                    {
                        response.TimestampOffset = ulong.Parse(videotrack.FirstOrDefault().Element("c").Attribute("t").Value);
                    }
                    else
                    {
                        response.TimestampOffset = 0; // no timestamp, so it should be 0
                    }

                    ulong totalduration         = 0;
                    ulong durationpreviouschunk = 0;
                    ulong durationchunk;
                    int   repeatchunk;
                    foreach (var chunk in videotrack.Elements("c"))
                    {
                        durationchunk = chunk.Attribute("d") != null?ulong.Parse(chunk.Attribute("d").Value) : 0;

                        log.Info($"duration d {durationchunk}");

                        repeatchunk = chunk.Attribute("r") != null?int.Parse(chunk.Attribute("r").Value) : 1;

                        log.Info($"repeat r {repeatchunk}");

                        if (chunk.Attribute("t") != null)
                        {
                            ulong tvalue = ulong.Parse(chunk.Attribute("t").Value);
                            response.TimestampList.Add(tvalue);
                            if (tvalue != response.TimestampOffset)
                            {
                                totalduration = tvalue - response.TimestampOffset; // Discountinuity ? We calculate the duration from the offset
                                response.DiscontinuityDetected = true;             // let's flag it
                            }
                        }
                        else
                        {
                            response.TimestampList.Add(response.TimestampList[response.TimestampList.Count() - 1] + durationpreviouschunk);
                        }

                        totalduration += durationchunk * (ulong)repeatchunk;

                        for (int i = 1; i < repeatchunk; i++)
                        {
                            response.TimestampList.Add(response.TimestampList[response.TimestampList.Count() - 1] + durationchunk);
                        }

                        durationpreviouschunk = durationchunk;
                    }
                    response.TimestampEndLastChunk = response.TimestampList[response.TimestampList.Count() - 1] + durationpreviouschunk;

                    if (smoothmedia.Attribute("IsLive") != null && smoothmedia.Attribute("IsLive").Value == "TRUE")
                    { // Live asset.... No duration to read (but we can read scaling and compute duration if no gap)
                        response.IsLive        = true;
                        response.AssetDuration = TimeSpan.FromSeconds((double)totalduration / ((double)timescale));
                    }
                    else
                    {
                        totalduration          = ulong.Parse(smoothmedia.Attribute("Duration").Value);
                        response.AssetDuration = TimeSpan.FromSeconds((double)totalduration / ((double)timescale));
                    }
                }
                else
                {
                    response.Error = true;
                }
                if (mytemplocator != null)
                {
                    mytemplocator.Delete();
                }
            }
            catch (Exception ex)
            {
                response.Error = true;
            }
            return(response);
        }
示例#27
0
        public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log)
        {
            log.Info($"Webhook was triggered!");

            string jsonContent = await req.Content.ReadAsStringAsync();

            dynamic data = JsonConvert.DeserializeObject(jsonContent);

            log.Info("Request : " + jsonContent);

            var attachedstoragecred = KeyHelper.ReturnStorageCredentials();

            // Validate input objects
            if (data.assetId == null)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass assetId in the input object" }));
            }

            if (data.targetStorageAccountName == null)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass targetStorageAccountName in the input object" }));
            }
            if (data.targetStorageAccountKey == null)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass targetStorageAccountKey in the input object" }));
            }
            if (data.targetContainer == null)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass targetContainer in the input object" }));
            }

            string targetStorageAccountName = data.targetStorageAccountName;
            string targetStorageAccountKey  = data.targetStorageAccountKey;
            string targetContainer          = data.targetContainer;
            string startsWith = data.startsWith;
            string endsWith   = data.endsWith;


            log.Info("Input - targetStorageAccountName : " + targetStorageAccountName);
            log.Info("Input - targetStorageAccountKey : " + targetStorageAccountKey);
            log.Info("Input - targetContainer : " + targetContainer);
            string assetId = data.assetId;

            IAsset          asset    = null;
            IIngestManifest manifest = null;

            MediaServicesCredentials amsCredentials = new MediaServicesCredentials();

            log.Info($"Using Azure Media Service Rest API Endpoint : {amsCredentials.AmsRestApiEndpoint}");

            try
            {
                AzureAdTokenCredentials tokenCredentials = new AzureAdTokenCredentials(amsCredentials.AmsAadTenantDomain,
                                                                                       new AzureAdClientSymmetricKey(amsCredentials.AmsClientId, amsCredentials.AmsClientSecret),
                                                                                       AzureEnvironments.AzureCloudEnvironment);

                AzureAdTokenProvider tokenProvider = new AzureAdTokenProvider(tokenCredentials);

                _context = new CloudMediaContext(amsCredentials.AmsRestApiEndpoint, tokenProvider);


                // Find the Asset
                asset = _context.Assets.Where(a => a.Id == assetId).FirstOrDefault();
                if (asset == null)
                {
                    return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Asset not found" }));
                }


                string storname = amsCredentials.StorageAccountName;
                string storkey  = amsCredentials.StorageAccountKey;
                if (asset.StorageAccountName != amsCredentials.StorageAccountName)
                {
                    if (attachedstoragecred.ContainsKey(asset.StorageAccountName)) // asset is using another storage than default but we have the key
                    {
                        storname = asset.StorageAccountName;
                        storkey  = attachedstoragecred[storname];
                    }
                    else // we don't have the key for that storage
                    {
                        log.Info($"Face redaction Asset is in {asset.StorageAccountName} and key is not provided in MediaServicesAttachedStorageCredentials application settings");
                        return(req.CreateResponse(HttpStatusCode.BadRequest, new
                        {
                            error = "Storage key is missing"
                        }));
                    }
                }


                // Setup blob container
                CloudBlobContainer sourceBlobContainer      = CopyBlobHelpers.GetCloudBlobContainer(storname, storkey, asset.Uri.Segments[1]);
                CloudBlobContainer destinationBlobContainer = CopyBlobHelpers.GetCloudBlobContainer(targetStorageAccountName, targetStorageAccountKey, targetContainer);
                destinationBlobContainer.CreateIfNotExists();

                var files = asset.AssetFiles.ToList().Where(f => ((string.IsNullOrEmpty(endsWith) || f.Name.EndsWith(endsWith)) && (string.IsNullOrEmpty(startsWith) || f.Name.StartsWith(startsWith))));

                foreach (var file in files)
                {
                    CloudBlob sourceBlob      = sourceBlobContainer.GetBlockBlobReference(file.Name);
                    CloudBlob destinationBlob = destinationBlobContainer.GetBlockBlobReference(file.Name);
                    CopyBlobHelpers.CopyBlobAsync(sourceBlob, destinationBlob);
                    log.Info($"Start copy of file : {file.Name}");
                }
            }
            catch (Exception ex)
            {
                string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : "");
                log.Info($"ERROR: Exception {message}");
                return(req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message }));
            }

            return(req.CreateResponse(HttpStatusCode.OK));
        }
示例#28
0
        public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log)

        {
            log.Info($"Webhook was triggered!");

            string jsonContent = await req.Content.ReadAsStringAsync();

            dynamic data = JsonConvert.DeserializeObject(jsonContent);

            log.Info(jsonContent);

            if (data.channelName == null)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new
                {
                    error = "Please pass channelName in the input object"
                }));
            }
            if (data.programName == null)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, new
                {
                    error = "Please pass programName in the input object"
                }));
            }
            string   channelName = data.channelName;
            string   programName = data.programName;
            IProgram program     = null;

            MediaServicesCredentials amsCredentials = new MediaServicesCredentials();

            log.Info($"Using Azure Media Service Rest API Endpoint : {amsCredentials.AmsRestApiEndpoint}");

            try
            {
                AzureAdTokenCredentials tokenCredentials = new AzureAdTokenCredentials(amsCredentials.AmsAadTenantDomain,
                                                                                       new AzureAdClientSymmetricKey(amsCredentials.AmsClientId, amsCredentials.AmsClientSecret),
                                                                                       AzureEnvironments.AzureCloudEnvironment);

                AzureAdTokenProvider tokenProvider = new AzureAdTokenProvider(tokenCredentials);

                _context = new CloudMediaContext(amsCredentials.AmsRestApiEndpoint, tokenProvider);

                log.Info("Context object created.");

                var channel = _context.Channels.Where(c => c.Name == channelName).FirstOrDefault();
                if (channel == null)
                {
                    return(req.CreateResponse(HttpStatusCode.BadRequest, new
                    {
                        error = string.Format("Channel {0} not found", channelName)
                    }));
                }

                program = channel.Programs.Where(p => p.Name.Equals(programName)).FirstOrDefault();
                if (program == null)
                {
                    return(req.CreateResponse(HttpStatusCode.BadRequest, new
                    {
                        error = string.Format("Program {0} not found", programName)
                    }));
                }

                log.Info("Stoping program...");
                program.Stop();
                log.Info("Program stopped.");
            }
            catch (Exception ex)
            {
                string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : "");
                log.Info($"ERROR: Exception {message}");
                return(req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message }));
            }

            return(req.CreateResponse(HttpStatusCode.OK, new
            {
                success = true,
                state = program.State.ToString()
            }));
        }