Extract audio from video using autogen ffmpeg C# in Unity - c#

Hi I'm using ffmpeg autogen to extract audio from video in Unity, but when I following this code, the file write cannot write, it's 0Kb, so what's issue of this or someone have any examples for extract audio using this library, apologize for my English. This is github of library:
https://github.com/Ruslan-B/FFmpeg.AutoGen
unsafe void TestExtractAudio()
{
string inFile = Application.streamingAssetsPath + "/" + strFileName;
string outFile = Application.streamingAssetsPath + "/" + strFileNameAudio;
AVOutputFormat* outFormat = null;
AVFormatContext* inFormatContext = null;
AVFormatContext* outFormatContext = null;
AVPacket packet;
ffmpeg.av_register_all();
inFormatContext = ffmpeg.avformat_alloc_context();
outFormatContext = ffmpeg.avformat_alloc_context();
if (ffmpeg.avformat_open_input(&inFormatContext, inFile, null, null) < 0)
{
throw new ApplicationException("Could not open input file.");
}
if (ffmpeg.avformat_find_stream_info(inFormatContext, null) < 0)
{
throw new ApplicationException("Failed to retrieve input stream info.");
}
ffmpeg.avformat_alloc_output_context2(&outFormatContext, null, null, outFile);
if (outFormatContext == null)
{
throw new ApplicationException("Could not create output context");
}
outFormat = outFormatContext->oformat;
AVStream* inStream = inFormatContext->streams[1];
AVStream* outStream = ffmpeg.avformat_new_stream(outFormatContext, inStream->codec->codec);
if (outStream == null)
{
throw new ApplicationException("Failed to allocate output stream.");
}
if (ffmpeg.avcodec_copy_context(outStream->codec, inStream->codec) < 0)
{
throw new ApplicationException("Couldn't copy input stream codec context to output stream codec context");
}
outFormatContext->audio_codec_id = AVCodecID.AV_CODEC_ID_MP3;
int retcode = ffmpeg.avio_open(&outFormatContext->pb, outFile, ffmpeg.AVIO_FLAG_WRITE);
if (retcode < 0)
{
throw new ApplicationException("Couldn't open output file");
}
int returnCode = ffmpeg.avformat_write_header(outFormatContext, null);
if (returnCode < 0)
{
throw new ApplicationException("Error occurred opening output file.");
}
while (true)
{
if (ffmpeg.av_read_frame(inFormatContext, &packet) < 0)
{
break;
}
if (packet.stream_index == 1)
{
inStream = inFormatContext->streams[1];
outStream = outFormatContext->streams[0];
// TODO: Replicate log packet functionality to print out what's inside the packet.
packet.pts = ffmpeg.av_rescale_q_rnd(packet.pts, inStream->time_base, outStream->time_base,
AVRounding.AV_ROUND_NEAR_INF | AVRounding.AV_ROUND_PASS_MINMAX);
packet.dts = ffmpeg.av_rescale_q_rnd(packet.dts, inStream->time_base, outStream->time_base,
AVRounding.AV_ROUND_NEAR_INF | AVRounding.AV_ROUND_PASS_MINMAX);
packet.duration = ffmpeg.av_rescale_q(packet.duration, inStream->time_base, outStream->time_base);
int returncode = ffmpeg.av_interleaved_write_frame(outFormatContext, &packet);
}
ffmpeg.av_packet_unref(&packet);
}
ffmpeg.av_write_trailer(outFormatContext);
ffmpeg.avformat_close_input(&inFormatContext);
ffmpeg.avformat_free_context(outFormatContext);
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
the value returnCode return less than 0, so someone can fix this, thanks so much for that

The problem is here:
inStream = inFormatContext->streams[1];
outStream = outFormatContext->streams[0];
This code:
ffmpeg.av_interleaved_write_frame
does the following validation
static int check_packet(AVFormatContext *s, AVPacket *pkt)
{
if (pkt->stream_index < 0 || pkt->stream_index >= s->nb_streams) {
av_log(s, AV_LOG_ERROR, "Invalid packet stream index: %d\n"
}
you need to change the packet.stream_index from 1 to 0 before calling
int returncode = ffmpeg.av_interleaved_write_frame(outFormatContext, &packet);
See:
if (type == AVMediaType.AVMEDIA_TYPE_AUDIO){
inStream = inFormatContext->streams[1];
outStream = outFormatContext->streams[0];
// TODO: Replicate log packet functionality to print out what's inside the packet.
ffmpeg.av_packet_rescale_ts(&packet, inStream->time_base, outStream->time_base);
packet.stream_index = 0;
int returncode = ffmpeg.av_write_frame(outFormatContext, &packet);
}

Related

Access to the path denied. C# unable to create

I am working on a PGP decryption code...here all access to the directory is granted in security tab and path exists but at the end of decryption where the decrypted file is created and to be placed this error occurs
code
--- path declaration----
string outputPath = ConfigurationManager.AppSettings["OutPutPath"];
--- in app config
<add key="OutPutPath" value="D:\Decryption\Output"/>
--- checking path is existing or not
(here it shows that the path exists)
if (!Directory.Exists(outputPath))
{
Directory.CreateDirectory(outputPath);
}
decryption
Crypto.Decrypt(item, privateKeyPath, DecipherTextPhrase.Trim(), outputPath);
public static void Decrypt(Stream inputStream, Stream privateKeyStream, string passPhrase, string outputFile)
{
try
{
PgpObjectFactory pgpF = null;
PgpEncryptedDataList enc = null;
PgpObject o = null;
PgpPrivateKey sKey = null;
PgpPublicKeyEncryptedData pbe = null;
PgpSecretKeyRingBundle pgpSec = null;
pgpF = new PgpObjectFactory(PgpUtilities.GetDecoderStream(inputStream));
// find secret key
pgpSec = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream));
if (pgpF != null)
o = pgpF.NextPgpObject();
// the first object might be a PGP marker packet.
if (o is PgpEncryptedDataList)
enc = (PgpEncryptedDataList)o;
else
enc = (PgpEncryptedDataList)pgpF.NextPgpObject();
// decrypt
foreach (PgpPublicKeyEncryptedData pked in enc.GetEncryptedDataObjects())
{
sKey = FindSecretKey(pgpSec, pked.KeyId, passPhrase.ToCharArray());
if (sKey != null)
{
pbe = pked;
break;
}
}
if (sKey == null)
throw new ArgumentException("Secret key for message not found.");
PgpObjectFactory plainFact = null;
using (Stream clear = pbe.GetDataStream(sKey))
{
plainFact = new PgpObjectFactory(clear);
}
PgpObject message = plainFact.NextPgpObject();
if (message is PgpCompressedData)
{
PgpCompressedData cData = (PgpCompressedData)message;
PgpObjectFactory of = null;
using (Stream compDataIn = cData.GetDataStream())
{
of = new PgpObjectFactory(compDataIn);
}
message = of.NextPgpObject();
if (message is PgpOnePassSignatureList)
{
message = of.NextPgpObject();
PgpLiteralData Ld = null;
Ld = (PgpLiteralData)message;
if (!string.IsNullOrEmpty(Ld.FileName))
outputFile = outputFile + (Ld.FileName.EndsWith(".txt")? Ld.FileName:Ld.FileName+".txt");
else
outputFile = outputFile + "test" + DateTime.Now.ToString("yyyyMMddHHmm") + ".txt";
using (Stream output = File.Create(outputFile))
{
Stream unc = Ld.GetInputStream();
Streams.PipeAll(unc, output);
}
}
else
{
PgpLiteralData Ld = null;
Ld = (PgpLiteralData)message;
using (Stream output = File.Create(outputFile)) ----**error occurs here**
{
Stream unc = Ld.GetInputStream();
Streams.PipeAll(unc, output);
}
}

How to convert PDF to Image using iTextsharp?

I used this code but not getting correct format Image.
give better way to convert pdf to Image using iTextsharp.
FileStream fs = File.OpenRead(ImagePath);
byte[] data = new byte[fs.Length];
fs.Read(data, 0, (int)fs.Length);
List<System.Drawing.Image> ImgList = new List<System.Drawing.Image>();
iTextSharp.text.pdf.RandomAccessFileOrArray RAFObj = null;
iTextSharp.text.pdf.PdfReader PDFReaderObj = null;
iTextSharp.text.pdf.PdfObject PDFObj = null;
iTextSharp.text.pdf.PdfStream PDFStremObj = null;
try
{
RAFObj = new iTextSharp.text.pdf.RandomAccessFileOrArray(data);
PDFReaderObj = new iTextSharp.text.pdf.PdfReader(RAFObj, null);
for (int k = 0; k <= PDFReaderObj.XrefSize - 1; k++)
{
PDFObj = PDFReaderObj.GetPdfObject(k);
if ((PDFObj != null) && PDFObj.IsStream())
{
PDFStremObj = (iTextSharp.text.pdf.PdfStream)PDFObj;
iTextSharp.text.pdf.PdfObject subtype = PDFStremObj.Get(iTextSharp.text.pdf.PdfName.SUBTYPE);
if ((subtype != null) && subtype.ToString() == iTextSharp.text.pdf.PdfName.IMAGE.ToString())
{
byte[] bytes = iTextSharp.text.pdf.PdfReader.GetStreamBytesRaw((iTextSharp.text.pdf.PRStream)PDFStremObj);
if ((bytes != null))
{
try
{
System.IO.MemoryStream MS = new System.IO.MemoryStream(bytes);
MS.Position = 0;
System.Drawing.Image ImgPDF = System.Drawing.Image.FromStream(MS);
ImgList.Add(ImgPDF);
}
catch (Exception ex)
{
}
}
}
}
}
PDFReaderObj.Close();
}
catch (Exception ex) { throw ex; }
}
above coded getting file from ImagePath using FileStream to pdfobject and then memorystream to Image.

Streaming FFMPEG RTSP in C#

I wish to stream an RTSP feed from my camera through my C# client app and eventually recieve it on my server.
To test it I decided to stream it through my client and then recieve the jpeg frames from it as well.
I 1st tested my command line arguments in a DOS window.
It worked in that it stream to an output file without incident.
So, now I ported it over to my C# app and used the Process Class.
This is the code:
Task.Run(() =>
{
try
{
process.Start();
byte[] buffer = new byte[200000];
baseStream = process.StandardOutput.BaseStream as FileStream;
bool gotHeader = false;
bool imgFound = false;
int counter = 0;
while (true)
{
byte bit1 = (byte)baseStream.ReadByte();
buffer[counter] = bit1;
if (bit1 == 217 && gotHeader)
{
if (buffer[counter - 1] == 255)
{
byte[] jpeg = new byte[counter];
Buffer.BlockCopy(buffer, 0, jpeg, 0, counter);
using (MemoryStream ms = new MemoryStream(jpeg))
{
pictureBox1.Image = Image.FromStream(ms);
ms.Close();
}
imgFound = true;
}
}
else if (bit1 == 216)
{
if (buffer[counter - 1] == 255)
{
gotHeader = true;
}
}
if (imgFound)
{
counter = 0;
buffer = new byte[200000];
imgFound = false;
gotHeader = false;
}
else
{
counter++;
}
}
}
catch (Exception ex2)
{
//log error here
}
});
But I do not get any images I just get the byte value of 255 at this line:
buffer[counter] = bit1;
So.. what am I doing wrong please?
Thanks

TcpClient performance on Xamarin.Android

I have encountered a problem with TcpClient running on an Android device. The issue is that reading from NetworkStream takes a lot of time. I use it to send bitmaps from server application (also written in C#) to my Android device (Nexus 9). I push 6000 bitmaps each of them around 1.4KB in size. That takes around 30 seconds to complete (5ms per bitmap). On the other hand I also implemented the same in Java and it takes 5 seconds to do the same (less than 1ms per bitmap)!
Are you aware of any issues regarding TcpClient in Xamarin.Android? I have to admit that this is very surprising as I have never had similar problems with Xamarin.
I pasted just a little code below so you can take a look if it is not me that messed up something. At the very bottom I also pasted Java code and as you can see it is very similar. Do you have any suggestions regarding this? I appreciate any feedback.
Here is the method that I use to receive bitmaps (this function runs asynchronously and is started through Task.Factory.StartNew()):
private void HandleRequestBitmaps(TcpClient client, CancellationToken token)
{
if (client == null)
{
throw new ArgumentNullException("client");
}
var encoder = new UTF8Encoding();
using (var stream = client.GetStream())
{
stream.WriteMessageWithLength(ServerCommand.PushBitmaps.ServerCommandToBytes(encoder));
var initialMetadataBytes = stream.ReadMessageWithLength(client.ReceiveBufferSize);
int[] initialMetadata;
if (!TryParseMetadataMessage(initialMetadataBytes, encoder, 3, out initialMetadata))
{
BitmapReceiveEnd(this, new BitmapReceiveEndEventArgs(false));
return;
}
BitmapsReceiveBegin(this,
new BitmapsReceiveBeginEventArgs(initialMetadata[0], initialMetadata[1], initialMetadata[2]));
while (!token.IsCancellationRequested)
{
var messageBytes = stream.ReadMessageWithLength(client.ReceiveBufferSize);
if (ServerCommand.PushBitmapsDone.Equals(messageBytes.BytesToServerCommand(encoder)))
{
BitmapReceiveEnd(this, new BitmapReceiveEndEventArgs(true));
break;
}
int[] metadata;
if (!TryParseMetadataMessage(messageBytes, encoder, 3, out metadata))
{
BitmapReceiveEnd(this, new BitmapReceiveEndEventArgs(false));
return;
}
var bitmapBytes = stream.ReadMessageWithLength(client.ReceiveBufferSize);
BitmapReceived(this,
new BitmapReceivedEventArgs(metadata[0], new Point(metadata[1], metadata[2]), bitmapBytes));
}
}
}
Where TryParseMetadaMessage method looks like this:
private static bool TryParseMetadataMessage(byte[] message, Encoding encoder, int expectedLength,
out int[] metadata)
{
var messageString = encoder.GetString(message, 0, message.Length);
var messageStringSeparated = messageString.Split('x');
if (messageStringSeparated.Length != expectedLength)
{
metadata = new int[0];
return false;
}
var parameteres = new List<int>();
foreach (var messageStringPart in messageStringSeparated)
{
int value;
if (!int.TryParse(messageStringPart, out value))
{
metadata = new int[0];
return false;
}
parameteres.Add(value);
}
metadata = parameteres.ToArray();
return true;
}
}
Also ReadMessage with length looks like this:
public static byte[] ReadMessageWithLength(this Stream stream, int bufferSize = 2048)
{
if (stream == null)
{
throw new ArgumentNullException("stream");
}
var messageSizeBuffer = new byte[4];
if (stream.Read(messageSizeBuffer, 0, messageSizeBuffer.Length) < 1)
{
return new byte[0];
}
if (BitConverter.IsLittleEndian)
{
Array.Reverse(messageSizeBuffer);
}
var totalBytesToRead = BitConverter.ToInt32(messageSizeBuffer, 0);
if (totalBytesToRead < 0)
{
throw new Exception("Number of bytes to read cannot be negative!");
}
using (var memoryStream = new MemoryStream())
{
var buffer = new byte[bufferSize];
int chunkBytesRead, totalBytesRead = 0;
while (
(chunkBytesRead = stream.Read(buffer, 0, Math.Min(totalBytesToRead - totalBytesRead, buffer.Length))) >
0)
{
memoryStream.Write(buffer, 0, chunkBytesRead);
totalBytesRead += chunkBytesRead;
if (totalBytesRead >= totalBytesToRead)
{
break;
}
}
return memoryStream.ToArray();
}
}
Now time for Java code. The function used to receive bitmaps:
public void requestBitmaps() {
if (socket == null || !socket.isConnected()) {
throw new IllegalStateException("Socket has to be initialized and connected to call this method!");
}
requestBitmapsThread = new Thread(new Runnable() {
#Override
public void run() {
try {
InputStream sis = new BufferedInputStream(socket.getInputStream());
OutputStream sos = new BufferedOutputStream(socket.getOutputStream());
writeMessageWithLength(sos, ServerCommand.PushBitmaps.getValueBytes());
byte[] initialMetadataBytes = readMessageWithLength(sis, socket.getReceiveBufferSize());
int[] initialMetadata = parseMetadataMessage(initialMetadataBytes, 3);
if (initialMetadata == null) {
listener.onBitmapReceivedEnd(false);
return;
}
listener.onBitmapReceivedBegin(initialMetadata[0], initialMetadata[1], initialMetadata[2]);
while (!Thread.currentThread().isInterrupted()) {
byte[] messageBytes = readMessageWithLength(sis, socket.getReceiveBufferSize());
if (ServerCommand.PushBitmapsDone.equals(ServerCommand.fromValueBytes(messageBytes))) {
listener.onBitmapReceivedEnd(true);
break;
}
int[] metadata = parseMetadataMessage(messageBytes, 3);
if (metadata == null) {
listener.onBitmapReceivedEnd(false);
break;
}
byte[] bitmapBytes = readMessageWithLength(sis, socket.getReceiveBufferSize());
listener.onBitmapReceived(metadata[0], metadata[1], metadata[2], bitmapBytes);
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
requestBitmapsThread.start();
}
And also parseMetadataMessage method:
private int[] parseMetadataMessage(byte[] metadataBytes, int expectedLength) {
String metadataString = new String(metadataBytes, Charset.forName("UTF-8"));
String[] metadataStringSeparated = metadataString.split("x");
if (metadataStringSeparated.length != expectedLength) {
return null;
}
try {
int[] parameters = new int[metadataStringSeparated.length];
for (int i = 0; i < metadataStringSeparated.length; i++) {
parameters[i] = Integer.parseInt(metadataStringSeparated[i]);
}
return parameters;
} catch (NumberFormatException e) {
e.printStackTrace();
return null;
}
}
And readMessageWithLength:
private byte[] readMessageWithLength(InputStream is, int bufferLength) throws IOException {
byte[] messageLengthBuffer = new byte[4];
if (is.read(messageLengthBuffer) < 0) {
return null;
}
ByteBuffer messageLengthByteBuffer = ByteBuffer.wrap(messageLengthBuffer).order(ByteOrder.BIG_ENDIAN);
int totalBytesToRead = messageLengthByteBuffer.getInt();
if (totalBytesToRead < 0) {
throw new IllegalStateException("Total bytes to read cannot be less than 0!");
}
ByteArrayOutputStream bitmapBytesBuffer = null;
try {
bitmapBytesBuffer = new ByteArrayOutputStream();
byte[] buffer = new byte[bufferLength];
int chunkBytesRead, totalBytesRead = 0;
while ((chunkBytesRead = is.read(buffer, 0, Math.min(totalBytesToRead - totalBytesRead, buffer.length))) > 0) {
bitmapBytesBuffer.write(buffer, 0, chunkBytesRead);
totalBytesRead += chunkBytesRead;
if (totalBytesRead >= totalBytesToRead) {
break;
}
}
return bitmapBytesBuffer.toByteArray();
} finally {
if (bitmapBytesBuffer != null) {
bitmapBytesBuffer.close();
}
}
}
If you have come this far, thanks for attention. I appreciate any feedback and I hope it will be possible to speed up the code.
Best regards,
Bartosz

Unzip files in Windows Phone 8 - 'System.OutOfMemoryException'

I used the UnZipper class from this (How to unzip files in Windows Phone 8) post in my app for zips with images, but in some rare cases it gives me this error:
A first chance exception of type 'System.OutOfMemoryException' occurred in System.Windows.ni.dll System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown. at System.Windows.Application.GetResourceStreamInternal(StreamResourceInfo zipPackageStreamResourceInfo, Uri resourceUri) at System.Windows.Application.GetResourceStream(StreamResourceInfo zipPackageStreamResourceInfo, Uri uriResource) at ImperiaOnline.Plugins.UnZipper.GetFileStream(String filename) at ImperiaOnline.Plugins.IOHelpers.unzip(String zipFilePath, String zipDestinationPath)
The device has more then twice needed free memory. Can somebody help me with this. Here is my code:
public static void unzip(string zipFilePath,string zipDestinationPath) {
using (IsolatedStorageFile isolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
var dirNames = isolatedStorage.GetDirectoryNames(zipDestinationPath);
bool doesFolderExists = (dirNames.Length > 0) ? true : false;
if (!doesFolderExists)
{
Debug.WriteLine("Folder does not exists");
isolatedStorage.CreateDirectory(zipDestinationPath);
}
try
{
using (IsolatedStorageFileStream zipFile = isolatedStorage.OpenFile(zipFilePath, FileMode.Open, FileAccess.ReadWrite))
{
UnZipper unzip = new UnZipper(zipFile);
bool isModuleFolderDeleted = false;
foreach (string currentFileAndDirectory in unzip.FileNamesInZip())
{
string[] fileLocations = currentFileAndDirectory.Split('/');
string prefix = zipDestinationPath + '/';
int locationsCount = fileLocations.Length;
string fileName = fileLocations.Last();
string currentPath = prefix;
for (int i = 0; i < locationsCount - 1; i++)
{
dirNames = isolatedStorage.GetDirectoryNames(currentPath + fileLocations[i]);
doesFolderExists = (dirNames.Length > 0) ? true : false;
if (!doesFolderExists)
{
isolatedStorage.CreateDirectory(currentPath + fileLocations[i]);
if (i == 2)
{
isModuleFolderDeleted = true;
}
}
else if (i == 2 && !isModuleFolderDeleted)
{
Debug.WriteLine(currentPath + fileLocations[i] + " is deleted and recreated");
DeleteDirectoryRecursively(isolatedStorage, currentPath + fileLocations[i]);
isolatedStorage.CreateDirectory(currentPath + fileLocations[i]);
isModuleFolderDeleted = true;
}
currentPath += fileLocations[i] + '/';
}
var newFileStream = isolatedStorage.CreateFile(currentPath + fileName);
byte[] fileBytes = new byte[unzip.GetFileStream(currentFileAndDirectory).Length];
unzip.GetFileStream(currentFileAndDirectory).Read(fileBytes, 0, fileBytes.Length);
unzip.GetFileStream(currentFileAndDirectory).Close();
try
{
newFileStream.Write(fileBytes, 0, fileBytes.Length);
}
catch (Exception ex)
{
Debug.WriteLine("FILE WRITE EXCEPTION: " + ex);
newFileStream.Close();
newFileStream = null;
zipFile.Close();
unzip.Dispose();
}
newFileStream.Close();
newFileStream = null;
}
zipFile.Close();
unzip.Dispose();
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
isolatedStorage.DeleteFile(zipFilePath);
}
}
This error appears here:
var newFileStream = isolatedStorage.CreateFile(currentPath + fileName);
byte[] fileBytes = new byte[unzip.GetFileStream(currentFileAndDirectory).Length]; unzip.GetFileStream(currentFileAndDirectory).Read(fileBytes, 0, fileBytes.Length);
unzip.GetFileStream(currentFileAndDirectory).Close();
I debugged it and it fails on
byte[] fileBytes = new byte[unzip.GetFileStream(currentFileAndDirectory).Length];
I checked GetFileStream method
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;
}
It throws OutOfMemory exception on this row:
StreamResourceInfo stream = System.Windows.Application.GetResourceStream(info, fileUri);

Categories

Resources