C# Media Transcoder PrepareMediaStreamSourceTranscodeAsync issue - c#

I want to perform media transcoding operation in-memory using Media Foundation from a MP3 format to a WAV (PCM) format.
I tried the code as mentioned below:
//Initialize MediaStreamSource with location of MP3 file
var mediaStream = new MediaStreamSource(mp3File);
//Create a "dummy" wav file to attach to IRandomAccessStream
StorageFile _OutputFile2 = await
KnownFolders.VideosLibrary.CreateFileAsync("Test.wav",
CreationCollisionOption.GenerateUniqueName);
IRandomAccessStream iras =
_OutputFile2.OpenAsync(FileAccessMode.ReadWrite).AsTask().Result;
//Setup the transcode operation to convert from MP3 to WAV
_Profile = MediaEncodingProfile.CreateWav(audioEncodingProfile);
var preparedTranscodeResult = await
_Transcoder.PrepareMediaStreamSourceTranscodeAsync(mediaStream, iras,
_Profile);
try
{
if (preparedTranscodeResult.CanTranscode)
{
var progress = new Progress<double>(TranscodeProgress);
await
preparedTranscodeResult.TranscodeAsync().AsTask(_cts.Token,
progress);
}
else
{
TranscodeFailure(preparedTranscodeResult.FailureReason);
}
}
catch (Exception ex)
{
TranscodeError(ex.Message);
}
When trying to transcode, I get the following error:
This object needs to be initialized before the requested operation can
be carried out.
I also referred this link which has a similar issue:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/6156580a-6673-4cf3-b6a9-5853b2a85bf6/what-kind-of-stream-to-feed-into-mediatranscoderpreparestreamtranscodeasync?forum=winappswithnativecode
I am looking for a sample which performs in-memory transcode operation instead of saving it to disk.
Appreciate your help.

Related

Stream video from RavenDB through ASP.Net MVC

I'm trying to stream a Video, that is saved as an attachment in a Ravendb-Database, through an ASP.NET MVC 5 Action to a WebBrowser. It is working with the following Code, but the Video gets fully downloaded before the Video starts. I don't get what I'm doing wrong.
I found some ways to do Streaming in MVC, but they seem to expect a Seekable Stream - but the stream I receive from Ravendb is not seekable; it even does not provide a length. So the only way of doing it would be to copy the ravendb-stream to a memorystream and provide a PartialContent or similar from there.
Does anybody have a better solution? I cannot be the only one that wants to stream a Video from a database without loading the full Video into Memory before sending it.
I'm fetching the attachment from ravendb like this:
public async Task<System.IO.Stream> GetAttachmentAsync(IAttachmentPossible attachedObject, string key)
{
using (var ds = InitDatabase())
{
using (var session = ds.OpenAsyncSession())
{
try
{
var result = await session.Advanced.Attachments.GetAsync(attachedObject.Id, key);
return result.Stream;
}
catch (Exception ex)
{
return null;
}
}
}
}
After that I send the stream to the browser like this:
var file = await _database.GetAttachmentAsync(entry, attachmentId);
HttpResponseMessage msg = new HttpResponseMessage(HttpStatusCode.OK);
msg.Content = new StreamContent(file);
msg.Content.Headers.ContentType = new MediaTypeHeaderValue("video/mp4");
return msg;
Any ideas? Thank you very much!
I think that it is correct to copy the stream into a memory stream. With the answer you linked (https://stackoverflow.com/a/39247028/10291808) you can do streaming.
Maybe could be an idea to think about the multiple calls that will done to retrieve the file from the db (maybe you could cache the file for a limited time to improve performance).

UWP BitmapEncoder SetProperties is not supported

So I'm creating a UWP app and need to write text and images to an image file and save them. I've currently created a D2D wrapper in C++ using this source and then a C# wrapper that simply lets you access the functions of the C++ class in nice C# code (it does nothing else but access the WINMD C++ wrapper).
However, after we write the image and text to the stream, we need to be able to save the file with EXIF headers containing info about rotation and location.
We are using encoder.BitmapProperties.SetPropertiesAsync to accomplish this, but it returns:
Exception thrown: 'System.Exception' in Tester.exe
Additional information: The operation is unsupported. (Exception from HRESULT: 0x88982F81)
There is no inner exception and the stack trace is:
at Windows.Graphics.Imaging.BitmapEncoder.get_BitmapProperties()
at Tester.ViewModels.<_SaveImageWithPropertiesAsync>d__56.MoveNext()
I want to try to avoid manually adding the headers, as I fear the returned stream from the D2DContext doesn't contain any header information or whatnot so it can't append anything to it.
Here is the relevant part of my code:
C++
Again, you can find the original source here
IRandomAccessStream^ D2DWrapper::EndDraw()
{
DX::ThrowIfFailed(
m_d2dContext->EndDraw()
);
// If needPreview is true, we return a valid IRandomAccessStream reference.
GUID wicFormat = GUID_ContainerFormatBmp;
ComPtr<IStream> stream;
ComPtr<ISequentialStream> ss;
auto inMemStream = ref new InMemoryRandomAccessStream();
DX::ThrowIfFailed(
CreateStreamOverRandomAccessStream(inMemStream, IID_PPV_ARGS(&stream))
);
SaveBitmapToStream(m_targetBitmap, m_wicFactory, m_d2dContext, wicFormat, stream.Get());
return inMemStream;
}
C# Wrapper
public IRandomAccessStream EndDraw() {
return _context.EndDraw()
}
C# Tester
async Task _SaveImageWithPropertiesAsync(UWPImaging.Image image, PhotoOrientation photoOrientation)
{
var ras = await image.EndDraw();
var decoder = await BitmapDecoder.CreateAsync(ras);
var file = await KnownFolders.PicturesLibrary.CreateFileAsync(
"test.jpeg",
CreationCollisionOption.GenerateUniqueName);
using (var outputStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateForTranscodingAsync(outputStream, decoder);
var properties = new BitmapPropertySet { { "System.Photo.Orientation", new BitmapTypedValue(photoOrientation, PropertyType.UInt16) } };
await encoder.BitmapProperties.SetPropertiesAsync(properties); // This is where the error occurs
await encoder.FlushAsync();
}
}
Any help on how to get those headers in would be much appreciated!
Thanks,
Nolan
If the target container is different (ex. JPEG to TIFF), then you need to modify metadata before writing them, according to the target container specifications. WIC Explorer can help you understand the metadata structure of files. I found that some codecs (ex. HEIF) freeze the app when trying to get all the available metadata, so better to manually pick what's needed.

Download and save a picture from a url Universal windows app

I am using the below code to downlaod the picture form a remote url and save to Local storage folder
try
{
var rootFolder = await ApplicationData.Current.LocalFolder.CreateFolderAsync( "MyAppName\\CoverPics", CreationCollisionOption.OpenIfExists);
var coverpic_file = await rootFolder.CreateFileAsync(filename, CreationCollisionOption.FailIfExists);
try
{
var httpWebRequest = HttpWebRequest.CreateHttp(coverUrl);
HttpWebResponse response = (HttpWebResponse)await httpWebRequest.GetResponseAsync();
Stream resStream = response.GetResponseStream();
using (var stream = await coverpic_file.OpenAsync(FileAccessMode.ReadWrite))
{
await resStream.CopyToAsync(stream.AsStreamForWrite());
}
response.Dispose();
}
catch //any exceptions happend while saving the picture
{
saved = false;
}
}
catch
{
//https://msdn.microsoft.com/en-us/library/windows/apps/br227250.aspx
//Raise an exception if file already present
saved = true;
}
This code is working for me in most of the cases , but i noticed that for few pictures the image is not downloading completely.
I am callling this function in an async block for more tahn 100 images in a single go inside the foreach loop and in the end few of them are failed downloads
[ Either i can see some invalid file is getting created
or part of image only in downloading and rest of the area i can see a black colour block [ looks like image is corrupted].
Size of all images is less than 1 MB only
Can some one help me to optimize this code or point out the mistake in code so i can able to download all the images completely
I am not seeing any error in my code. But after trying some different ways of downloading and saving a file my code looks like this and
try
{
HttpClient client = new HttpClient(); // Create HttpClient
byte[] buffer = await client.GetByteArrayAsync(coverUrl); // Download file
using (Stream stream = await coverpic_file.OpenStreamForWriteAsync())
stream.Write(buffer, 0, buffer.Length); // Save
}
catch
{
saved = false;
}
And this code is working fine without causing any issues All images are downloading completely and no more issues of black block on images.
If any one can points out the difference with my first code will be really helpful to understood the reason for error
Have you tried using new Windows.Web.Http.HttpClient instead of HttpWebRequest?
Also take a look this SO question :
How do I use the new HttpClient from Windows.Web.Http to download an image?
If you not familiar with HttpClient, I sugest to watch CH9 presentation :
https://channel9.msdn.com/Events/Build/2013/4-092
I tried your download and experienced the same issues.
var myFolder = await ApplicationData.Current.LocalFolder.CreateFolderAsync("MyFolderPath", CreationCollisionOption.OpenIfExists);
var myFile = await myFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
BackgroundDownloader downloader = new BackgroundDownloader();
DownloadOperation download = downloader.CreateDownload(new Uri(URL), myFile);
await download.StartAsync();

The component cannot be found. (Exception from HRESULT: 0x88982F50)

The above exception occurs at line await bitmapImage.SetSourceAsync(fileStream); whenever I tried to retrieve image from local file.
This is the method I'm using for storing and retrieving the image file.
public async Task<BitmapImage> RetrieveImageFromFile(String fileName)
{
try
{
StorageFile localFile = await _storageFolder.GetFileAsync(fileName + "Img");
BitmapImage bitmapImage = new BitmapImage();
using (IRandomAccessStream fileStream = await localFile.OpenAsync(FileAccessMode.Read))
{
await bitmapImage.SetSourceAsync(fileStream);
}
return bitmapImage;
}
catch(Exception e)
{
return null;
}
}
public async void WriteImageToFile(string fileName, IRandomAccessStreamWithContentType stream )
{
StorageFile file = await _storageFolder.CreateFileAsync(fileName + "Img", CreationCollisionOption.ReplaceExisting);
Stream streamToSave = stream.AsStreamForWrite();
using (Stream fileStram = await file.OpenStreamForWriteAsync())
{
streamToSave.CopyTo(fileStram);
}
}
The input stream for the WriteImageToFile method is retrieved from contact.Thumbnail.OpenReadAsync() method
Any help ?
Just turning my comment into an answer since it's been helping people:
The 0x88982f50 error is generally related to a failure to read/decode an image file correctly. Verify your file is formatted properly. Google 88982f50 to see dozens of potentially related fixes, all relating to image file I/O. I never did find a definitive source for the error but this turned out to be my problem as well... Bad file.
Late answer but might save someone else from spending hours hunting this down...
Error code 0x88982f50 is WINCODEC_ERR_COMPONENTNOTFOUND, and it's the Windows Imaging Component's way of saying it can't decode an image file.
Most likely the file is corrupted, or the version of WIC installed in Windows doesn't include a codec needed to decode it.
Microsoft provides zero information about it.

Unzipping files in WP8.1 Using SharpZipper

I am trying to use SharpZip.unzipper for my windows phone 8.1. However it is not reading some of the code. Since i am fairly new to windows phone development please let me know the alternatives of following code for WP8.1
using System.Windows.Resources;
public Stream GetFileStream(string filename)
{
if (fileEntries == null)
fileEntries = ParseCentralDirectory(); //We need to do this in case the zip is in a format Silverligth doesn't like
long position = this.stream.Position;
this.stream.Seek(0, SeekOrigin.Begin);
Uri fileUri = new Uri(filename, UriKind.Relative);
StreamResourceInfo info = new StreamResourceInfo(this.stream, null);
StreamResourceInfo stream = System.Windows.Application.GetResourceStream(info, fileUri);
this.stream.Position = position;
if (stream != null)
return stream.Stream;
return null;
}
Windows.Resources seems missing
I can't call StreamResourceInfo, System.Windows.Application
I have tried using App. but there is no function for GetResourceSteam
I am not sure what to do here
There are quite a few differences between WP8.1 runtime and WP8.1 Silverlight.
The code sample that you have will run on WP8.0 SL and WP8.1 SL.
It looks like you created a Windows Phone 8.1 runtime project. There is no System.Windows.Application.GetResourceStream()
Either convert it to a compatible 8.1 runtime stream or recreate your project to target Silverlight instead.
// sample
private async void ZipLibraryTest()
{
// create the full path
string zip = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "filename.zip");
// create the storage file with the file name
StorageFile sf = await StorageFile.GetFileFromPathAsync(zip);
// create the IO Stream
using (System.IO.Stream output = await sf.OpenStreamForWriteAsync())
{
// open the zip file for writing, use the stream from the file
ZipFile zf = ZipFile.Create(output);
// rest of your code
// ...
// ...
// close the zip file
zf.Close();
}
}

Categories

Resources