Set Content-type of media files stored on Blob
Asked Answered
B

11

108

We have a website hosted on Azure. It is media based, and we are using JWPlayer to playback media with HTTP pseudostreaming. The media files are stored on blob in 3 formats - mp4, ogg, webm.

The issue is the content type of media files is set as application/octet-stream for all types. Due to this there are some issues in media playback and progress bar.

How can I set the appropriate Content-type of files stored on blob (like - video/mp4, video/ogg, video/webm)?

I do not want to do it manually for each file by going in blob interface. There must be some other way to do it which I am not aware of. Perhaps a config file, settings file, etc sorts. Or perhaps a code block to set up the Content-type for all files stored in a folder.

Any suggestions? Thanks

Blois answered 6/4, 2012 at 7:19 Comment(0)
B
139

This should work:

var storageAccount = CloudStorageAccount.Parse("YOURCONNECTIONSTRING");
var blobClient = storageAccount.CreateCloudBlobClient();

var blobs = blobClient
    .GetContainerReference("thecontainer")
    .ListBlobs(useFlatBlobListing: true)
    .OfType<CloudBlockBlob>();

foreach (var blob in blobs)
{
    if (Path.GetExtension(blob.Uri.AbsoluteUri) == ".mp4")
    {
        blob.Properties.ContentType = "video/mp4";
    }
    // repeat ad nauseam
    blob.SetProperties();
}

Or set up a dictionary so you don't have to write a bunch of if statements.

Becket answered 6/4, 2012 at 7:36 Comment(5)
@smarx : Is it also possible to do the same thing in CDN, #21848163Nostology
Isn't there any possibility to set this up on Azure Portal directly? without codingDuval
Here is a blog post with a comprehensive list of extension to mimetype mappings. ppolyzos.com/2015/10/27/…Goat
It might be worth mentioning that if you have access to System.Web and .NET 4.5 or higher, you can call MimeMapping.GetMimeMapping("somefile.mp4") to get the content type. See MSDN for more details.Tananarive
this works even on dotnet coreReduplicative
T
87

Unfortunately, the accepted answer here is not currently working for the latest SDK (12.x.+)

With the latest SDK, the content type should be set via BlobHttpHeaders.

var blobServiceClient = new BlobServiceClient("YOURCONNECTIONSTRING");
var containerClient = blobServiceClient.GetBlobContainerClient("YOURCONTAINERNAME");
var blob = containerClient.GetBlobClient("YOURFILE.jpg");

var blobHttpHeader = new BlobHttpHeaders { ContentType = "image/jpeg" };
 
var uploadedBlob = await blob.UploadAsync(YOURSTREAM, new BlobUploadOptions { HttpHeaders = blobHttpHeader });

YOURSTREAM could be a new BinaryData(byte[])

Tarrsus answered 9/6, 2020 at 21:16 Comment(5)
It's working fine. In my opinion, currently this answer should be mark as accepted.Shiftless
Thank you for this. I couldn't find this anywhere in the 12.x documentation.Astylar
For anyone who's looking for Golang solution it should be: HTTPHeaders: &blob.HTTPHeaders{ BlobContentType: &contentType } and contentType := "application/pdf" somewhere when you specifying the upload option.Racialism
So how can I do this for all the blobs in my account?Thursby
@SoraTeichman you have to do this every time you upload the file. If you have a storage account the files do not have this information, perhaps you need to loop the whole container and then set the header informationTarrsus
I
14

This is work example to upload video to Azure Blob Storage with right Content-Type:

public static String uploadFile(
     CloudBlobContainer container,String blobname, String fpath) {

    CloudBlockBlob blob;
    try {
        blob = container.getBlockBlobReference(blobname);
        File source = new File(fpath);

        if (blobname.endsWith(".mp4")) {
            System.out.println("Set content-type: video/mp4");
            blob.getProperties().setContentType("video/mp4");
        }

        blob.upload(new FileInputStream(source), source.length());

        return blob.getUri().toString();
    } catch (URISyntaxException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (StorageException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return null;
}
Idona answered 14/8, 2013 at 11:9 Comment(0)
G
8

With Azure.Storage.Blogs (12.8.4), We can set content type of file as below. In Default, Azure Storage stores file in application/octet-stream, In case of *.svg file, doesn't properly render in html. So we have to save *.svg file in azure blob storage with content type image/svg+xml while uploading into blob.

Below is the code sample I got working.

  BlobServiceClient blobServiceClient = new BlobServiceClient("CONNECTIONSTRING");
  BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient("CONTAINERNAME");
  BlobClient blobClient = containerClient.GetBlobClient("BLOBNAME");
  try
  {

    Stream stream = file.OpenReadStream();
    await blobClient.UploadAsync(stream, true);
    blobClient.SetHttpHeaders(new BlobHttpHeaders() { ContentType = file.ContentType });
  }

ContentType Set on header should place just below the blobClient.UploadAsync().

Guttate answered 1/6, 2022 at 1:37 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Zamarripa
S
2

In python

azure_connection_str = libc.retrieve.get_any_secret('AZURE_STORAGE_CONNECTION')
blob_service_client = BlobServiceClient.from_connection_string(azure_connection_str)
blobs = blob_service_client.list_blobs()
my_content_settings = ContentSettings(content_type='video/mp4')

for blob in blobs:
    blob_client = blob_service_client.container_client.get_blob_client(blob)
    blob_client.set_http_headers(content_settings=my_content_settings)
Swithin answered 25/11, 2021 at 21:1 Comment(0)
R
1

With Azure Storage v10 SDK, blobs can be uploaded using BlockBlobURL as instructed in the Node.js quickstart:

const {
  Aborter,
  BlockBlobURL,
  ContainerURL,
  ServiceURL,
  SharedKeyCredential,
  StorageURL,
  uploadFileToBlockBlob
} = require("@azure/storage-blob");

const containerName = "demo";
const blobName = "quickstart.txt";
const content = "hello!";

const credentials = new SharedKeyCredential(
  STORAGE_ACCOUNT_NAME,
  ACCOUNT_ACCESS_KEY
);
const pipeline = StorageURL.newPipeline(credentials);
const serviceURL = new ServiceURL(
  `https://${STORAGE_ACCOUNT_NAME}.blob.core.windows.net`,
  pipeline
);

const containerURL = ContainerURL.fromServiceURL(serviceURL, containerName);
const blockBlobURL = BlockBlobURL.fromContainerURL(containerURL, blobName);

const aborter = Aborter.timeout(30 * ONE_MINUTE);
await blockBlobURL.upload(aborter, content, content.length);

Then content type can be set after the upload with the setHTTPHeaders method:

// Set content type to text/plain
await blockBlobURL.setHTTPHeaders(aborter, { blobContentType: "text/plain" });

Files can be uploaded with the uploadFileToBlockBlob method from @azure/storage-blob.

Ramsden answered 1/10, 2019 at 16:0 Comment(0)
A
0

Using php, one can upload the video by setting the content type as follows

$blobRestProxy = ServicesBuilder::getInstance()->createBlobService($connectionString);
//upload
$blob_name = "video.mp4";
$content = fopen("video.mp4", "r");

$options = new CreateBlobOptions();
$options->setBlobContentType("video/mp4");
try {
    //Upload blob
    $blobRestProxy->createBlockBlob("containername", $blob_name, $content, $options);
    echo "success";
} catch(ServiceException $e){
    $code = $e->getCode();
    $error_message = $e->getMessage();
    echo $code.": ".$error_message."<br />";
}
Allograph answered 19/3, 2014 at 6:52 Comment(1)
This does not work with current packages as of right now.Dorking
D
0

here is what i do

BlobHTTPHeaders h = new BlobHTTPHeaders();
String blobContentType = "image/jpeg";
h.withBlobContentType(blobContentType);
blobURL.upload(Flowable.just(ByteBuffer.wrap(Files.readAllBytes(img.toPath()))), img.length(), h, null, null, null)
.subscribe(resp-> {
  System.out.println("Completed upload request.");
  System.out.println(resp.statusCode());
});
Dinesen answered 29/9, 2018 at 22:58 Comment(0)
S
0

If you are having API in the middle which is used to upload files you can do something like this.

Using Azure.Storage.Files.Datalake v12.12.1 and Datalake storage Gen v2 you can specify content type using DataLakeFileUploadOptions.

using Azure.Storage.Files
using Microsoft.AspNetCore.StaticFiles;
(...)

public async Task<IActionResult> UploadAsync(string container, string uploadDirectoryPath, 
         IFormFile file) {
     var dataLakeServiceClient = new DataLakeServiceClient(connString);
     var dataLakeFileSystemClient = dataLakeServiceClient.GetFileSystemClient(container);
     var dataLakeFileClient = dataLakeFileSystemClient
                             .GetFileClient(Path.Combine(uploadDirectoryPath, file.FileName));
 
     var fileStream = file.OpenReadStream();
     var mimeType = GetMimeType(file.FileName);
     var uploadOptions = new DataLakeFileUploadOptions()
     {
         HttpHeaders = new PathHttpHeaders() { ContentType = mimeType }                
     };

     await dataLakeFileClient.UploadAsync(fileStream, uploadOptions);
     return Ok();
}

private string GetMimeType(string fileName)
{
    var provider = new FileExtensionContentTypeProvider();
    if (!provider.TryGetContentType(fileName, out var contentType))
    {
        contentType = "application/octet-stream";
    }
    return contentType;
}

More about content types and GetMimeType method that I am using here.

Swadeshi answered 29/3, 2023 at 10:13 Comment(0)
A
0

If you use a Shared Access Signature (SAS) URL to upload files to Azure Blob Storage, then you can set the Content-Type via an HTTP header on the HTTP PUT operation. The content type will then be displayed in the Azure Portal and will be properly set when downloading the blob from Azure Blob Storage.

var jsonFilePath = "...";
var uploadUrl = "https://<storageaccount>.blob.core.windows.net/<container>/<blob>?<SAS_token>";

using var jsonFileStream = File.OpenRead(jsonFilePath);
using var jsonFileContent = new StreamContent(jsonFileStream);

// Writing to Azure Blob Storage requires this specific HTTP header
jsonFileContent.Headers.Add("x-ms-blob-type", "BlockBlob");

// Set the content type of the file being uploaded
jsonFileContent.Headers.Add("Content-Type", "application/json");

using var jsonFileResponse = await _httpClient.PutAsync(uploadUrl, jsonFileContent);

if (!jsonFileResponse.IsSuccessStatusCode)
{
    throw new Exception($"Error Uploading File: {jsonFileResponse.StatusCode} {jsonFileResponse.ReasonPhrase}");
}
Arnica answered 19/12, 2023 at 23:53 Comment(0)
F
-1

You can use Azure Storage Explorer to do this manually. Right-click the file to change and select Properties. Go to ContentType and edit the value to the correct one i.e. "video\mp4"

Formant answered 8/10, 2021 at 10:49 Comment(1)
Can you edit this post to make it more assertive? Note that the Question says "I do not want to do it manually for each file by going in blob interface"Twocycle

© 2022 - 2024 — McMap. All rights reserved.