设置存储在 Blob 上的媒体文件的 Content-type

我们在 Azure 上有一个网站。它是基于媒体的,我们使用 JWPlayer 来播放带有 HTTP 伪流的媒体。媒体文件以3种格式存储在 blob 中—— mp4、 ogg、 webm。

问题在于媒体文件的内容类型被设置为所有类型的 application/octet-stream。由于这有一些问题在媒体播放和进度条。

如何设置存储在 blob 上的适当的 Content-type 文件(如-video/mp4、 video/ogg、 video/webm) ?

我不想在 blob 接口中为每个文件手动执行。一定还有其他我不知道的方法。也许是一个配置文件、设置文件等排序。或者可能是一个代码块,用于为存储在一个文件夹中的所有文件设置 Content-type。

有什么建议吗? 谢谢

90959 次浏览

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.

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;
}

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 />";
}

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());
});

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.

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[])

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"

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)

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().