我正在尝试将控制器上的mp4文件上传到azure blob存储中,当我完成上传后,我正在创建来自同一个blob的资产,我刚刚上传的每件事似乎都运转正常,但我不知道一些我怎么不能得到publishAssetURL
var manifestFile = asset.AssetFiles.Where(x =>
x.Name.EndsWith(".ism")).FirstOrDefault();
此问题就在这一行manifestFile
即将为空。
public string CreateAssetFromExistingBlobs(CloudBlobContainer sourceBlobContainer, CloudStorageAccount _destinationStorageAccount, CloudMediaContext _context, AzureStorageMultipartFormDataStreamProvider provider )
{
CloudBlobClient destBlobStorage = _destinationStorageAccount.CreateCloudBlobClient();
// Create a new asset.
IAsset asset = _context.Assets.Create("NewAsset_" + Guid.NewGuid(), AssetCreationOptions.None);
IAccessPolicy writePolicy = _context.AccessPolicies.Create("writePolicy",
TimeSpan.FromHours(24), AccessPermissions.Write);
ILocator destinationLocator =
_context.Locators.CreateLocator(LocatorType.Sas, asset, writePolicy);
// Get the asset container URI and Blob copy from mediaContainer to assetContainer.
CloudBlobContainer destAssetContainer =
destBlobStorage.GetContainerReference((new Uri(destinationLocator.Path)).Segments[1]);
if (destAssetContainer.CreateIfNotExists())
{
destAssetContainer.SetPermissions(new BlobContainerPermissions
{
PublicAccess = BlobContainerPublicAccessType.Blob
});
}
var blob = sourceBlobContainer.GetBlockBlobReference(provider.FileData.FirstOrDefault().LocalFileName);
blob.FetchAttributes();
var assetFile = asset.AssetFiles.Create(blob.Name);
CopyBlob(blob, destAssetContainer);
assetFile.ContentFileSize = blob.Properties.Length;
assetFile.Update();
asset.Update();
destinationLocator.Delete();
writePolicy.Delete();
// Set the primary asset file.
// If, for example, we copied a set of Smooth Streaming files,
// set the .ism file to be the primary file.
// If we, for example, copied an .mp4, then the mp4 would be the primary file.
var ismAssetFile = asset.AssetFiles.ToList().
Where(f => f.Name.EndsWith(".mp4", StringComparison.OrdinalIgnoreCase)).ToArray().FirstOrDefault();
// The following code assigns the first .ism file as the primary file in the asset.
// An asset should have one .ism file.
if (ismAssetFile != null)
{
ismAssetFile.IsPrimary = true;
ismAssetFile.Update();
}
IAsset encodedAsset = EncodeToAdaptiveBitrateMP4Set(asset, _context);
return PublishAssetGetURLs(encodedAsset, _context);
}
private void CopyBlob(ICloudBlob sourceBlob, CloudBlobContainer destinationContainer)
{
var signature = sourceBlob.GetSharedAccessSignature(new SharedAccessBlobPolicy
{
Permissions = SharedAccessBlobPermissions.Read,
SharedAccessExpiryTime = DateTime.UtcNow.AddHours(24)
});
var destinationBlob = destinationContainer.GetBlockBlobReference(sourceBlob.Name);
if (destinationBlob.Exists())
{
Console.WriteLine(string.Format("Destination blob '{0}' already exists. Skipping.", destinationBlob.Uri));
}
else
{
// Display the size of the source blob.
Console.WriteLine(sourceBlob.Properties.Length);
Console.WriteLine(string.Format("Copy blob '{0}' to '{1}'", sourceBlob.Uri, destinationBlob.Uri));
destinationBlob.StartCopy(new Uri(sourceBlob.Uri.AbsoluteUri + signature));
while (true)
{
// The StartCopyFromBlob is an async operation,
// so we want to check if the copy operation is completed before proceeding.
// To do that, we call FetchAttributes on the blob and check the CopyStatus.
destinationBlob.FetchAttributes();
if (destinationBlob.CopyState.Status != CopyStatus.Pending)
{
break;
}
//It's still not completed. So wait for some time.
System.Threading.Thread.Sleep(1000);
}
// Display the size of the destination blob.
Console.WriteLine(destinationBlob.Properties.Length);
}
}
private IAsset EncodeToAdaptiveBitrateMP4Set(IAsset asset, CloudMediaContext _context)
{
// Declare a new job.
IJob job = _context.Jobs.Create("Media Encoder Standard Job");
// Get a media processor reference, and pass to it the name of the
// processor to use for the specific task.
IMediaProcessor processor = GetLatestMediaProcessorByName("Media Encoder Standard",_context);
// Create a task with the encoding details, using a string preset.
// In this case "Adaptive Streaming" preset is used.
ITask task = job.Tasks.AddNew("My encoding task",
processor,
"Adaptive Streaming",
TaskOptions.None);
// Specify the input asset to be encoded.
task.InputAssets.Add(asset);
// Add an output asset to contain the results of the job.
// This output is specified as AssetCreationOptions.None, which
// means the output asset is not encrypted.
task.OutputAssets.AddNew("Output asset",
AssetCreationOptions.None);
job.StateChanged += new EventHandler<JobStateChangedEventArgs>(JobStateChanged);
job.Submit();
job.GetExecutionProgressTask(CancellationToken.None).Wait();
return job.OutputMediaAssets[0];
}
public void JobStateChanged(object sender, JobStateChangedEventArgs e)
{
//Console.WriteLine("Job state changed event:");
//Console.WriteLine(" Previous state: " + e.PreviousState);
//Console.WriteLine(" Current state: " + e.CurrentState);
switch (e.CurrentState)
{
case JobState.Finished:
//Console.WriteLine();
//Console.WriteLine("Job is finished. Please wait while local tasks or downloads complete...");
break;
case JobState.Canceling:
case JobState.Queued:
case JobState.Scheduled:
case JobState.Processing:
//Console.WriteLine("Please wait...\n");
break;
case JobState.Canceled:
case JobState.Error:
// Cast sender as a job.
IJob job = (IJob)sender;
// Display or log error details as needed.
break;
default:
break;
}
}
private IMediaProcessor GetLatestMediaProcessorByName(string mediaProcessorName, CloudMediaContext _context)
{
var processor = _context.MediaProcessors.Where(p => p.Name == mediaProcessorName).
ToList().OrderBy(p => new Version(p.Version)).LastOrDefault();
if (processor == null)
throw new ArgumentException(string.Format("Unknown media processor", mediaProcessorName));
return processor;
}
private string PublishAssetGetURLs(IAsset asset, CloudMediaContext _context)
{
// Create a 30-day readonly access policy.
// You cannot create a streaming locator using an AccessPolicy that includes write or delete permissions.
IAccessPolicy policy = _context.AccessPolicies.Create("Streaming policy",
TimeSpan.FromDays(30),
AccessPermissions.Read);
// Create a locator to the streaming content on an origin.
ILocator originLocator = _context.Locators.CreateLocator(LocatorType.OnDemandOrigin, asset,
policy,
DateTime.UtcNow.AddMinutes(-5));
// Display some useful values based on the locator.
//Console.WriteLine("Streaming asset base path on origin: ");
//Console.WriteLine(originLocator.Path);
//Console.WriteLine();
// Get a reference to the streaming manifest file from the
// collection of files in the asset.
var manifestFile = asset.AssetFiles.Where(x => x.Name.EndsWith(".ism")).FirstOrDefault();
// Create a full URL to the manifest file. Use this for playback
// in streaming media clients.
string urlForClientStreaming = originLocator.Path + manifestFile.Name + "/manifest";
// Console.WriteLine("URL to manifest for client streaming using Smooth Streaming protocol: ");
// Console.WriteLine(urlForClientStreaming);
// Console.WriteLine("URL to manifest for client streaming using HLS protocol: ");
return urlForClientStreaming + "(format=m3u8-aapl)";
// Console.WriteLine("URL to manifest for client streaming using MPEG DASH protocol: ");
// Console.WriteLine(urlForClientStreaming + "(format=mpd-time-csf)");
// Console.WriteLine();
}
答案 0 :(得分:1)
检查我们的日志 - 您没有获得流式URL的原因是编码作业失败。在EncodeToAdaptiveBitrateMP4Set()结束时,您应确认最终作业状态是否已完成(即成功)。查看编码器日志,似乎输入文件已损坏。