78

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

Vivek Jain
  • 3,703
  • 6
  • 26
  • 45
Rahul Patwa
  • 1,829
  • 3
  • 16
  • 17

6 Answers6

131

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.

Dai
  • 110,988
  • 21
  • 188
  • 277
user94559
  • 54,841
  • 6
  • 85
  • 93
  • 1
    @smarx : Is it also possible to do the same thing in CDN, http://stackoverflow.com/questions/21847663/changing-video-content-type-mime-type-in-cdn-in-drupal-7 – Hitesh Feb 19 '14 at 10:11
  • 1
    Isn't there any possibility to set this up on Azure Portal directly? without coding – Emil Oct 19 '16 at 15:54
  • 4
    Here is a blog post with a comprehensive list of extension to mimetype mappings. https://ppolyzos.com/2015/10/27/apply-proper-content-type-to-files-in-azure-storage-containers-based-on-file-extensions/ – dragon788 May 01 '17 at 18:08
  • 1
    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](https://docs.microsoft.com/en-us/dotnet/api/system.web.mimemapping.getmimemapping?view=netframework-4.7.2) for more details. – David Yates Dec 03 '18 at 21:31
25

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();
blobHttpHeader.ContentType = "image/png";
 
var uploadedBlob = await blob.UploadAsync(YOURSTREAM, blobHttpHeader);
Yodacheese
  • 3,884
  • 2
  • 26
  • 39
Mehmet Taha Meral
  • 1,913
  • 19
  • 23
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;
}
Vadym Dobroskok
  • 177
  • 1
  • 7
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 />";
}
Neeraj Dangol
  • 213
  • 1
  • 12
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());
});
0

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.

saaskis
  • 121
  • 9