Video Playing From Memory Stream - asp.net

I am working in asp.net c#. I want to play video from memory stream. I am encrypting and decrypting video. I am storing the decrypted video in memory stream, and want to play it, without saving. I have googled it and found number of post, but mostly the post are uncompleted or provided the link with directshow. I have also tried with directshow, but it's totally new for me and contains number of demos, that made a confusion which one to use for Memory stream.
I just want to play decrypted video data from memory stream . Please let me know what I can do, it will be more good if there is a sample available from any forums.
My decrypted code
public bool DecryptData(String inName, String outName, byte[] rijnKey, byte[] rijnIV)
{
FileStream fin = null;
FileStream fout = null;
CryptoStream decStream = null;
try
{
fin = new FileStream(inName, FileMode.Open, FileAccess.Read);
//Create variables to help with read and write.
byte[] bin = new byte[bufLen]; //This is intermediate storage for the encryption.
long rdlen = 0; //This is the total number of bytes written.
long totlen = fin.Length; //This is the total length of the input file.
int len; //This is the number of bytes to be written at a time.
RijndaelManaged rijn = new RijndaelManaged();
//DES ds = new DESCryptoServiceProvider();
decStream = new CryptoStream(fin, rijn.CreateDecryptor(rijnKey, rijnIV), CryptoStreamMode.Read);
//odkoduj testowy fragment
byte[] test = new byte[testHeader.Length];
decStream.Read(test, 0, testHeader.Length);
string contents = new StreamReader(decStream).ReadToEnd();
byte[] unicodes = Encoding.Unicode.GetBytes(contents);
MemoryStream msOutput = new MemoryStream(unicodes);
//here I have to implement player that plays from memory stream.
}
catch
{}
}

I have answered one question regarding encrypting and decryption of a video file but i can understand you don't want to save a physical copy of that file on client machine.
https://stackoverflow.com/a/58129727/9869635
But it is not possible to play a video file from memorystream (not sure about some paid third party tools)
so one way you can do it like below approach:
1: Save that file in client's "temp" folder e.g. "temp/myvideos/sample.mkv"
2: Make it hidden from properties (How to hide file in C#?)
3: Play the video from there
4: once it is played, delete all files from that custom folder from "temp" folder (myvideos).

The best way to do it today, that works for any platform... is to use Http Live Streaming and then you can either use a player that supports HLS or you can simply use the HTML5 video tag. See my updated answer below...
Play a video without a file on disk [Java]

Related

Xamarin.Forms: DirectoryNoFoundException on WritingBytes

i download a video from a server as bytes and write those bytes as mp4 to the phones harddrive in pcl:
byte[] stream = await VideoAPI.DownloadVideo(AdID);
File.WriteAllBytes("/storage/emulated/0/Android/data/com.companyname.interiorcircle/files/Movies/file.mp4", stream);
But this returns the following error:
(stream is not null)
{System.IO.DirectoryNotFoundException: Could not find a part of the path "/storage/emulated/0/Android/data/com.companyname.interiorcircle/files/Movies/file.mp4".
But that doesnt make sense, since I am writing the file and path.
Where is this error comming from?
(Wiredly enough, while testing this worked once, but then not again)
Thank you!
use the Environment.SpecialFolder to create a path, not a string variable.
byte[] stream = await VideoAPI.DownloadVideo(AdID);
string fullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "file.mp4"); //also you can create extra folders
File.WriteAllBytes(fullPath , stream);
also, you can use different folders such as;
Environment.SpecialFolder.MyVideos
Environment.SpecialFolder.Personel
Environment.SpecialFolder.ApplicationData
Environment.SpecialFolder.Templates
Environment.SpecialFolder.CommonApplicationData
Environment.SpecialFolder.MyMusic
Environment.SpecialFolder.MyPictures
Environment.SpecialFolder.Fonts
Environment.SpecialFolder.MyDocuments
Environment.SpecialFolder.Desktop

Get length of data from inputstream opened by content-resolver

I am doing video (and also photo) uploading to the server by using HttpURLConnection.
I have an Uri of a video. I open an InputStream this way:
InputStream inputStream = context.getContentResolver().openInputStream(uri);
As video file is pretty big, I can't buffer data while writing it into the outputStream. So I need to use setFixedLengthStreamingMode(contentLength) method of HttpURLConnection. But it requires "contentLength".
The question is, how to get the length of the video?
Please don't suggest getting filepath. On some devices it works, but it often fails (especially on Android 6). They say Uri doesn't necessarily represent a file.
I also stumbled onto situations when after opening device gallery (with Intent) I receive an Uri of a picture, but I fail trying to get filepath from it. So I believe it's not a good way to get filepath from Uri?
Try something like this:
void uploadVideo() {
InputStream inputStream = context.getContentResolver().openInputStream(uri);
// Your connection.
HttpURLConnection connection;
// Do connection setup, setDoOutput etc.
// Be sure that the server is able to handle
// chunked transfer encoding.
connection.setChunkedStreamingMode(0);
OutputStream connectionOs = connection.getOutputStream();
// Read and write a 4 KiB chunk a time.
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
connectionOs.write(buffer, 0, bytesRead);
}
// Close streams, do connection etc.
}
UPDATE: added setChunkedStreamingMode

Is there a cross-platform solution to ImageSource to byte[]?

I did researches and fell on this solution: http://forums.xamarin.com/discussion/22682/is-there-a-way-to-turn-an-imagesource-into-a-byte-array
Initial question: http://forums.xamarin.com/discussion/29569/is-there-a-cross-platform-solution-to-imagesource-to-byte#latest
We want to upload an image through a HTTP Post, here's what we tried:
HttpClient httpClient = new HttpClient ();
byte[] TargetImageByte = **TargetImageSource**; //How to convert it to a byte[]?
HttpContent httpContent = new ByteArrayContent (TargetImageByte);
httpClient.PostAsync ("https://api.magikweb.ca/debug/file.php", httpContent);
We also are having a hard time with the libraries we gotta include in the using clauses. It seems like using System.IO; works, but it doesn't give us access to classes like FileInfo or FileStream.
Anybody has any idea how this can be done aside from custom platform-specific converters?
Possibly a Xamarin.Forms.ImageSource function toByte()?
Lemme know if you need more information.
TargetImageSource is a Xamarin.Forms.ImageSource.
ImageSource TargetImageSource = null;
Solution (Sten was right)
The ImageSource has to originate from another type to exist, that previous type can be converted to a byte[]. In this case, I use the Xamarin.Forms.Labs to take a picture and it returns a MediaFile in which a FileStream is accessible through the Source property.
//--Upload image
//Initialization
HttpClient httpClient = new HttpClient ();
MultipartFormDataContent formContent = new MultipartFormDataContent ();
//Convert the Stream into byte[]
byte[] TargetImageByte = ReadFully(mediaFile.Source);
HttpContent httpContent = new ByteArrayContent (TargetImageByte);
formContent.Add (httpContent, "image", "image.jpg");
//Send it!
await httpClient.PostAsync ("https://api.magikweb.ca/xxx.php", formContent);
App.RootPage.NavigateTo (new ClaimHistoryPage());
The function:
public static byte[] ReadFully(Stream input)
{
using (MemoryStream ms = new MemoryStream()){
input.CopyTo(ms);
return ms.ToArray();
}
}
I think you're looking at it a bit backwards.
ImageSource is a way to provide a source image for Xamarin.Forms.Image to show some content. If you're already showing something on the screen your Image view was populated with data that came from elsewhere, such as a file or resource or stored in an array in memory... or however else you got that in the first place. Instead of trying to get that data back from ImageSource you can keep a reference to it and upload it as needed.
Maybe you can elaborate a bit on your particular need if you don't feel this solution applies to your case.
Pseudo code:
ShowImage(){
ImageSource imageSource = ImageSource.FromFile("image.png"); // read an image file
xf_Image.Source = imageSource; // show it in your UI
}
UploadImage(){
byte[] data = File.ReadAll("image.png");
// rather than
// byte[] data = SomeMagicalMethod(xf_Image.Source);
HttpClient.Post(url, data);
}
UPDATE:
Since you're taking a picture you can copy the MediaFile.Source stream into a memory stream, then you can reset the memory stream's position to point at the beginning of the stream so that you can read it once again and copy it to the http body.
Alternatively you can store the MediaFile.Source to a file and use ImageSource.FromFile to load it in the UI, and when necessary - you can copy the file's contents into an http post body.

ASP.NET to PowerPoint: File gets corrupted when adding image

I have used this example when exporting data to PowerPoint:
I have modified the GenerateSlidesFromDB() method:
public void GenerateSlidesFromDB()
{
string slideName = #"C:\Users\x\Desktop\output.pptx";
File.Copy(#"C:\Users\x\Desktop\Test.pptx", slideName, true);
using (PresentationDocument presentationDocument = PresentationDocument.Open(slideName, true))
{
PresentationPart presentationPart = presentationDocument.PresentationPart;
SlidePart slideTemplate = (SlidePart)presentationPart.GetPartById("rId2");
string firstName = "Test User";
SlidePart newSlide = CloneSlidePart(presentationPart, slideTemplate);
InsertContent(newSlide, firstName);
newSlide.Slide.Save();
DeleteTemplateSlide(presentationPart, slideTemplate);
presentationPart.Presentation.Save();
}
}
As you can see I overwrite the placeholder with "Test User", and it works like a charm.
I need to add an image (as a placeholder) to this pptx-file.
When I do that (and run the code again) I get a corrupted pptx-file?
Error message:
PowerPoint removed unreadable content
in output.pptx. You should review
this presentation to determine whether
any content was unexpectedly changed
or removed.
Edit: If I try the original code (which is slightly modified since I dont have Adventureworks), I get some other kind of error message:
This file may have become corrupt or damaged for the following reasons:
Third-party XML editors sometimes create files that are not compatible with Microsoft Office XML specifications.
The file has been purposely corrupted with the intent to harm your computer or your data.
Be cautious when opening a file from an unknown source.
PowerPoint can attempt to recover data from the file, but some presentation data, such as shapes, text,and formatting, may be lost.
Do one of the following:
If you want to recover data from the file, click Yes.
If you do not want to recoverdata from the file, click No.
Ok, sorry for this useless post. My bad.
Solution:
string imgId = "rIdImg" + i;
ImagePart imagePart = newSlide.AddImagePart(ImagePartType.Jpeg, imgId);
MemoryStream stream3 = new MemoryStream();
using (FileStream file = File.Open(#"C:\Users\x\Desktop\Test.jpg", FileMode.Open))
{
byte[] buffer = new byte[file.Length];
file.Read(buffer, 0, (int)file.Length);
stream3.Write(buffer, 0, buffer.Length);
imagePart.FeedData(new MemoryStream(buffer));
}
SwapPhoto(newSlide, imgId);

Stream Video with ASP.NET

Is there a good way to stream video through asp.net to a normal webpage and mobile? I've tried the following but it doesn't work in my Sony Ericsson K810i. When I try it in my browser, I can see the clip (don't know if it's streaming though).
html:
<object type="video/3gpp"
data="handlers/FileHandler.ashx"
id="player"
width="176"
height="148"
autoplay="true"></object>
FileHandler.ashx (Best way to stream files in ASP.NET):
public void ProcessRequest (HttpContext context) {
string path = "~/files/do.3gp";
string localPath = context.Server.MapPath(path);
if (!File.Exists(localPath))
{
return;
}
// get info about contenttype etc
FileInfo fileInfo = new FileInfo(localPath);
int len = (int)fileInfo.Length;
context.Response.AppendHeader("content-length", len.ToString());
context.Response.ContentType = FileHelper.GetMimeType(fileInfo.Name); // returns video/3gpp
// stream file
byte[] buffer = new byte[1 << 16]; // 64kb
int bytesRead = 0;
using(var file = File.Open(localPath, FileMode.Open))
{
while((bytesRead = file.Read(buffer, 0, buffer.Length)) != 0)
{
context.Response.OutputStream.Write(buffer, 0, bytesRead);
}
}
// finish
context.Response.Flush();
context.Response.Close();
context.Response.End();
}
What you've got isn't "technically" streaming. It's a file download. Your client (browser/phone) sent an HTTP request and your FileHandler.ashx opened the file and wrote the bytes into the response stream. This is exactly the same interaction for a web page request except the data is html text rather than binary data representing a video.
If the phone isn't supporting the video it might be incompatible encoding. If you're sure the video is playable by the phone, see if the phone wants progressive download support (like the iPhone / iPad / iPod Touch require for the media player to "stream" videos.) If this is so, you'll need to look at any of a number of solutions that are available for handling requests for byte-range data and responding to the request with the bytes from the file in the range specified.
I wrote a library for ASP.NET MVC to handle this and my work was mostly done based on this guidance and source code.

Resources