/// <summary> /// Creates a watermark filter which displays the watermark image in the top left corner of the video<para /> /// /// API endpoint: /// https://bitmovin.com/docs/encoding/api-reference/sections/filters#/Encoding/PostEncodingFiltersEnhancedWatermark /// </summary> private Task <WatermarkFilter> CreateWatermarkFilter() { var watermarkFilter = new WatermarkFilter() { Image = _configProvider.GetWatermarkImagePath(), Top = 10, Left = 10 }; return(_bitmovinApi.Encoding.Filters.Watermark.CreateAsync(watermarkFilter)); }
private async Task ExecuteDownload( DownloadRequest request, HttpResponse httpResponse, FileModel fileModel, long?from = 0, long?to = 0, CancellationToken cancellationToken = default(CancellationToken) ) { // setup a handler to configure response headers void doHeaders(DownloadHeaderInformation headerInfo) { if (from != 0 || to != null) { httpResponse.StatusCode = 206; httpResponse.Headers.Add("Content-Range", new ContentRangeHeaderValue( headerInfo.RangeFrom, headerInfo.RangeTo, headerInfo.RangeLength ).ToString()); } var contentDisposition = new ContentDispositionHeaderValue(request.Open ? "inline" : "attachment"); contentDisposition.SetHttpFileName(headerInfo.FileName); httpResponse.Headers[HeaderNames.ContentDisposition] = contentDisposition.ToString(); httpResponse.Headers[HeaderNames.Pragma] = "no-cache"; httpResponse.Headers[HeaderNames.AcceptRanges] = "bytes"; } if (WatermarkFilter.IsSupportedFileType(fileModel.Extension) && EDiscoveryUtility.IsUserEDiscovery(Connection.UserAccessIdentifiers)) { // we're going to inject the Watermarker into the stream processing // so we don't use the standard FileDownloadAsync overload, instead we pass a stream callback await Connection.File.DownloadAsync( fileModel.Identifier, onDownloadHeaderInformation : doHeaders, onStreamAvailable : async(stream, cancel) => { // If we're downloading a child file, for instance in the case of a docx, we're generating a pdf. // when we generate that pdf, it won't inherit the metadata around eDiscovery. We need to get that file info, so we can get a share package name. FileIdentifier parentIdentifier; FileModel parentFileModel = fileModel; if ((parentIdentifier = fileModel.MetaChildOfRead()) != null) { parentFileModel = await Connection.File.GetAsync(parentIdentifier); } else { parentFileModel = fileModel; } // stream is a readstream of the file from the API server // pass that to the Watermarker adn the HTTPResponse body stream as the output // We need to get the path name for this file, which will give us what the discovery package it's in. var packageName = parentFileModel.Read <string>(MetadataKeyConstants.E_DISCOVERY_SHARE_PACKGAGE); var watermarkUser = await Connection.User.GetAsync(Connection.UserIdentifier); // this code is redundant with PathService.DownloadZip await WatermarkFilter.Execute(stream, httpResponse.Body, fileModel.Extension, $"Defense {packageName} {watermarkUser.EmailAddress}" ); }, from : from, to : to, cancellationToken : cancellationToken ); } else { await Connection.File.DownloadAsync( fileModel.Identifier, onDownloadHeaderInformation : doHeaders, onStreamAvailable : (stream, cancel) => stream.CopyToAsync(httpResponse.Body), from : from, to : to, cancellationToken : cancellationToken ); } }
public async Task DownloadZip( string fileName, IEnumerable <FileIdentifier> fileIdentifiers, HttpResponse response, Func <FileModel, PathIdentifier> pathGenerator = null, CancellationToken cancellationToken = default(CancellationToken) ) { if (pathGenerator == null) { pathGenerator = APIModelExtensions.MetaPathIdentifierRead; } response.StatusCode = 200; response.ContentType = "application/zip"; var contentDisposition = new ContentDispositionHeaderValue("attachment"); contentDisposition.SetHttpFileName(fileName); response.Headers[HeaderNames.ContentDisposition] = contentDisposition.ToString(); var isEDiscoveryUser = EDiscoveryUtility.IsUserEDiscovery(Connection.UserAccessIdentifiers); OrganizationModel organization = null; using (var archive = new ZipArchive(response.Body, ZipArchiveMode.Create)) { foreach (var fileIdentifier in fileIdentifiers) { if (organization == null || organization.Identifier.OrganizationKey != fileIdentifier.OrganizationKey) { organization = await Connection.Organization.GetAsync(fileIdentifier as OrganizationIdentifier); } var fileModel = await Connection.File.GetAsync(fileIdentifier); var views = ViewSetService.DetectFileViews(organization, fileModel); var newFileExtension = null as string; var contentsFileIdentifier = fileIdentifier; if (views.Any()) { var first = views.First(); switch (first.ViewerType) { case ManagerFileView.ViewerTypeEnum.Video: var mediaSet = await viewSetService.LoadSet <MediaSet>(fileIdentifier); var mp4 = mediaSet.Sources.FirstOrDefault(s => s.Type == "video/mp4"); if (mp4 != null) { newFileExtension = "mp4"; contentsFileIdentifier = mp4.FileIdentifier; } break; case ManagerFileView.ViewerTypeEnum.Document: if (fileModel.Extension == "docx") { var documentSet = await viewSetService.LoadSet <DocumentSet>(fileIdentifier); var pdf = documentSet.FileIdentifier; if (pdf != null) { newFileExtension = "pdf"; contentsFileIdentifier = pdf; } } break; } } var path = pathGenerator(fileModel); string name = fileModel.Name; if (newFileExtension != null) { name = $"{Path.GetFileNameWithoutExtension(name)}.{newFileExtension}"; } else { newFileExtension = fileModel.Extension; } name = MakeFilenameSafe(name); var filename = path != null ? Path.Combine(path.PathKey, name) : name; var entry = archive.CreateEntry(filename); using (var fileStream = entry.Open()) { await Connection.File.DownloadAsync( contentsFileIdentifier, onStreamAvailable : async(stream, cancel) => { if (isEDiscoveryUser && WatermarkFilter.IsSupportedFileType(newFileExtension)) { var packageName = fileModel.Read <string>( MetadataKeyConstants.E_DISCOVERY_SHARE_PACKGAGE); var watermarkUser = await Connection.User.GetAsync(Connection.UserIdentifier); // this code is redundant with FileService.ExecuteDownload await WatermarkFilter.Execute(stream, fileStream, newFileExtension, $"Defense {packageName} {watermarkUser.EmailAddress}" ); } else { await stream.CopyToAsync(fileStream); } }, cancellationToken : cancellationToken ); } } } }