How to implement Captioning in Azure Media services V3? - azure-media-services

How to complete captioning in azure media service 3by using .net SDK
I am using Azure Media Services v3 tutorials (https://github.com/Azure-Samples/media-services-v3-dotnet-tutorials) but missing How to update a video caption file(vtt file) into a media service asset by using .net SDK. Can some body help me on same.

You would simply treat the caption file the same way as you would a video that you upload. The only difference is that the caption file would be put into an asset that already has video. In other words, you'd upload your video, encode it, and in the output asset you'd upload the VTT file.
From a code perspective you would use:
// Use Media Services API to get back a response that contains
// SAS URL for the Asset container into which to upload blobs.
// That is where you would specify read-write permissions
// and the exparation time for the SAS URL.
var response = await client.Assets.ListContainerSasAsync(
resourceGroupName,
accountName,
assetName,
permissions: AssetContainerPermission.ReadWrite,
expiryTime: DateTime.UtcNow.AddHours(4).ToUniversalTime());
var sasUri = new Uri(response.AssetContainerSasUrls.First());
// Use Storage API to get a reference to the Asset container
// that was created by calling Asset's CreateOrUpdate method.
CloudBlobContainer container = new CloudBlobContainer(sasUri);
var blob = container.GetBlockBlobReference(Path.GetFileName(fileToUpload));
// Use Strorage API to upload the file into the container in storage.
await blob.UploadFromFileAsync(fileToUpload);
Where assetName is the name of your output asset.

How were you planning to deliver captions for playback? For the example in the Azure Media Player, the VTT file is added as a separate URL (from the HLS or DASH streaming URL). If this works, then you can simply edit the streaming URL and add the file name of the VTT file (as shown in one of the examples in the player page).
If, however, you need playback of captions via other HLS or DASH players, then there are some additional steps needed to expose the captions track along with video and audio. We will update our documentation pages when certain service updates have been deployed.

Related

AWS S3 storage does not give a valid URL after uploading file

I am new to AWS. I use Amplify to upload a video file to S3 storage using Flutter. I want to get the URL after uploading a video to use it elsewhere. I use Amplify.Storage.getUrl(key)).url to get the URL. But when I want to go to the link via the browser, it shows the following error there:
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<Error>
<Code>AccessDenied</Code>
<Message>No AWSAccessKey was presented.</Message>
<RequestId>AK49EW70AR8N1NVC</RequestId>
<HostId>Z6FBLU/GABRvJKFX827m3HoIKfVIpU0iXmH3gwSpcu04nNiqqEFjHZGGLn3VyyVNMY7ndK541ro=
</HostId>
</Error>
And also this link doesn't work when I want to play a video using VideoPlayerController.network(videoUrl).
So what is the solution to get a general URL for the video file uploaded that can be used elsewhere? Thanks in advance.

How to remove query string from Firebase Storage download URL

Problem:
I need to be able to remove all link decoration from the download URL that is generated for images in Firebase Storage.
However, when all link decoration is stripped away, the resulting link currently would return a JSON document of the image's metadata.
Context:
The flow goes as follows:
An image is uploaded to Firebase from an iOS app. Once that is done the download URL is then sent in a POST request to an external server.
The server that the URL is being sent to doesn't accept link decoration when submitting image URLs.
Goal:
Alter the Firebase Storage download URL such as it is stripped of all link decoration like so:
https://firebasestorage.googleapis.com/v0/b/example.appspot.com/o/[FOLDER_NAME]%[IMAGE_NAME].jpg
Notes:
The problem is twofold really, first the link needs to be manipulated to remove all the link decoration. Then the behavior of the link needs to changed, since in order to return an image, you need ?alt=media following the file extension, in this case .jpg. Currently, without link decoration, using the link with my desired structure would return a JSON document of the metadata.
The current link structure is as follows:
https://firebasestorage.googleapis.com/v0/b/example.appspot.com/o/[FOLDER_NAME]%[IMAGE_NAME].jpg?alt=media&token=[TOKEN]
Desired link structure:
https://firebasestorage.googleapis.com/v0/b/example.appspot.com/o/[FOLDER_NAME]%[IMAGE_NAME].jpg
The token is necessary for accessing the image depending security rules in place, but can be ignored with the proper read permissions. I can adjust the rules as needed, but I still need to be able to remove the ?alt=media and still return an image.
Building up on Frank's answer, if you access to your associated Google Cloud Platform project, find the bucket in the Storage tab and make this bucket public, you will be able to get the image from here with the format you wish. That is, you will not be accessing through Firebase
https://firebasestorage.googleapis.com/v0/b/example.appspot.com/o/[FOLDER_NAME]%[IMAGE_NAME].jpg
but through Google Cloud Storage, with a link like
https://storage.googleapis.com/[bucket_name]/[path_to_image]
Once in your GCP project Console, access the Storage bucket with the same name as the one you have in your Firebase project. They are the same bucket. Then make the bucket public by following these steps. After that, you will be able to construct your links as mentioned above and they will be accessible with no token and no alt=media param. If you do not want to make the public to everyone, you will be able to play around with the permissions there as you wish.
You could split the url string into two halves by using String.componentsSeparatedByString(_ separator:)
Storage.storage().reference().child(filePath).downloadURL(completion: { (url, error) in
let urlString = url.absoluteString
let urlStringWithoutQueryString = urlString.componentsSeparatedByString("?").first!
})
Calling .downloadURL on a StorageReference will return you that URL, but this method can be used to remove the query string from any URL. String.componentsSeparatedByString(_ separator:) breaks a String into an array of Strings, splitting the string by any occurrence of a given separator, in this case ?.
NOTE this method assumes that ? occurs only once within the url string, which I believe is the case for all Firebase Storage urls.
You should treat the download URL that you get back from Firebase as an opaque string. There's no way to strip the parameters from a download URL without breaking that download URL.
If you want to allow public access to the files in your bucket with simpler URLs, consider making the object in your (or even your entire) bucket public.

How do I play an audio file when using Fulfillment with Dialogflow

I'm making a Google Assistant action, similar to what Google does when you say "Play an E note".
I've managed to get my nodejs app to reply back the parameter, but now I need to pass an audio file. How do I do that?
The typical way to do this is to place the audio file on a hosting service somewhere (Firebase Hosting is a good choice, particularly if you're also using Firebase Cloud Functions for your Action, but any place that can serve a file via HTTPS works) and then send back SSML as your response that includes the audio.
This might look something like this:
var audioUrl = 'https://example.com/audiofile.mp3';
var msg = `<speak><audio src="${audioUrl}"></audio></speak>`
app.tell( msg );
Adjust this for your own audio file, and you might want to use app.ask() instead of tell if you are prompting the user to reply to your audio.

Delete a file by rev or id

I am uploading images to dropbox via the API call seen here:
var promise_uploadDropbox = xhr('https://content.dropboxapi.com/1/files_put/auto/Screenshot.png?overwrite=false', {
aMethod: 'PUT',
Headers: {
Authorization: 'Bearer ' + gEditor.dropboxOauth.access_token,
'Content-Type': myBlob.type,
'Content-Length': myBlob.size
},
aPostData: myBlob,
aResponseType: 'json'
});
I save in history the response.path for future, so I can delete this image, however if the user renames the image on the dropbox web app, then this delete operation will fail. Is there a way to find an image by a given rev or other identification, as this is supplied in the response object of the api call above.
Backstory for this need
I have created a Firefox addon. In this addon users take a screenshot and then edit/crop it, then save it, after the save is complete I copy to the clipboard the file or http path to the image so they can use in forums in galleries, etc etc etc (aside: perm img link important). People like the option of cloud storage so I am brining Dropbox.
I keep a history of the users actions in a HTLM5 application, form this dashboard, I give users a quick way to copy image link, or delete from server the file. (aside: another point where a perm link to the image is important as its an offline app, and I show the image in the )`
Here is a image of my dashboard:
The upcoming Dropbox API v2 (currently in preview) has a concept of IDs for files, and you will indeed be able to delete by file ID in API v2.
But for API v1 (the current version), no such ID exists.
EDIT: I thought deleting by file ID already worked in API v2, but it turns out it doesn't! It will by v2 release, though.

GWT GAE Upload through Blob

If I'm using GWT File widget and form panel, can someone explain how to handle upload on blobstore on google application engine??
Take a look at gwtupload. There are examples on how to use it with GAE Blobstore.
Google blobstore is specifically designed to upload and serve blobs via http. Blobstore service (obtained using BlobstoreServiceFactory.getBlobstoreService()) generates http post action for you to use in the html form. By posting file to it you upload your blob to the blobstore. When you generate this action you provide a path to the handler (servlet) where you have access to uploaded blob key:
Map<String, BlobKey> blobs = blobstoreService.getUploadedBlobs(req);
BlobKey blobKey = blobs.get("data");
Note, that "data" is the file field in your form. All you have is a key to the blob (your file). From here you take control - you can save this key for later and/or immediately serve the blob on a page (using key):
BlobKey blobKey = new BlobKey(req.getParameter("blob-key"));
blobstoreService.serve(blobKey, res);
Of course, for details see Google documentation.
One nice feature of the blobstore that it's integrated with Google Mapper (rudimentary map-reduce) service (work in progress) which lets you process files uploaded as blobs line by line: http://ikaisays.com/2010/08/