I am trying to split a large AVI 2.0 (OpenDML format) file in smaller parts (under 1GB in my case) in order to be able to open the parts with VFW (avifil32.dll).
What is the best way to achieve this splitting (preferably in C#)?
One of the options is to copy it frame by frame. I found some examples on the net, which do the same. But most of these use VFW which can't read files above 2GB in general and AVI 2.0 files above 1GB because of the max RIFF part size of 1GB.
I would need DirectShow instead of VFW. I am pretty sure that I would also mess up the audio sync if I try to manually copy frames.
I am looking for something similar to what VirtualDub does with "direct stream copy" that doesn't affect the current compression, just splits the file and creates proper AVI indexes.
Avi files can be encoded in many different ways, depending on the codec used. Avi is a wrapper file, not an encoding method. This means there isn't really an easy generic way to split avi files using C#.
To do it in code from scratch would be a major undertaking. That said, you can cheat by using mencoder and calling it from c# - not ideal, but far easier and more reliable than trying to re-invent the wheel. Alternatively, there are a number of ffmpeg c# wrappers that will give you access the ffmpeg tools (but I haven't found one that isn't buggy as hell)
What are you trying to do, exactly? Why do you need avifil32.dll and how are you using it? If you are just trying to play a very large avi file, there are alternatives. Try aforge.net, for example.
mencoder can split files for you. Another option is ffmpeg
Related
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
bitmaps to avi file c# .Net
I am bit struck with an idea to convert the sequence image files into a single video file. I am using dotnet as a platform.How should i proceed. No clear idea...
And more to that need to add audio(mp3) speech while the image sequenceare displayed...
The general idea here is you want to pass your raw images through an encoder and encode the file that way. The encoder will take care of generating all your keyframes and intermediary (P and B) frames as well as generating any necessary decoding metadata that needs to be stored. On top of that running it through an encoding tool such as ffmpeg will also take care of saving the video file in a known container format and properly structuring your video headers. All of this is complicated and tedious to do by hand, not to mention error prone.
Whether you use ffmpeg or some other encoder it's up to you. I suggest using ffmpeg because it has the necessary functionality you need. If you want to do this all in code, ffmpeg is open source and you can wrap the pieces you need in a .net shell and call things that way. Though, keep in mind ffmpeg's licenses if you are developing a distributable application.
This should get you started: Making movies from image files using ffmpeg/mencoder
To add audio check this: https://stackoverflow.com/questions/1329333/how-can-i-add-audio-mp3-to-a-flv-just-video-with-ffmpeg
Now if you want to synchronize the audio and video (lets say the image sequence is people talking and the audio is their speech) you have a much more difficult problem on your hands. At this point you need to properly multiplex audio and video frames based on their durations. FFMpeg probably won't do that well since it will set each image in your video sequence to play at the same duration, which doesn't usually correlate properly with audio frames.
The following code works with some wav files, but with others I get, "InvalidOperationException was unhandled. Message=Sound API only supports playing PCM wave files."
var webClient = new WebClient();
webClient.DownloadFile(url, fileName);
var fileSound = new SoundPlayer(fileName);
fileSound.PlaySync();
Is there a way to programmatically check if a wav file is "bad" (not a PCM wave file) and then convert it as necessary?
What is odd is that the code works in the legacy Delphi app - all of the wav files play just fine. Here's the Delphi code:
filename := GetEnvironmentVariable('TEMP')+'\archieAndDingbat.wav';
URLDownloadToFile(nil, PChar(url), PChar(filename), 0, nil);
PlaySound(filename);
I looked at the properties of the two files in Explorer, and I see that there is, indeed, a difference. For the file that does play, its audio format is PCM; the one that won't play is CCITT u-Law.
So...I either need a way to convert from CCITT u-Law to PCM on the fly after downloading these files (they are download from an url and then played locally) OR perhaps a different way of playing these files than PlaySync() ...
Look at audiolab library from mitov. It works great
So, do you want to PLAY the file or CONVERT it ? What is the primary goal ? Do you play it as a prove you can convert it, or do you convert it because you don't know how to play not-converted file ?
http://www.catb.org/esr/faqs/smart-questions.html#goal
Your question's title claims "convert" but the body claims "Play"
This answer is about playing files.
You also may try to use FFDShow codecs directly without DirectX intermediate.
http://en.wikipedia.org/wiki/Libavcodec and http://libav.org/ and http://ffmpeg.org/ (they recently had a schism)
Googling for "FFDShow dotnet", "libav dotnet", "ffmpeg dotnet" shows a bunch of libraries to use it, such as
https://github.com/ermau/libav.net
Controlling ffdshow from .Net
Solid FFmpeg wrapper for C#/.NET
There is also BASS library. It is targeted as sound playback during gaming, so it probably has less range of formats and not much for re-coding. Still many music players are built on top of it. Some says it is the most simple API to use. So it worth considering. http://www.un4seen.com/
http://MediaInfo.sf.net is a library (native win32/win64 DLL) allowing to check most multimedia formats content.
I don't know if using tis C or C++ APis is easy from C# side.
The way to do it is to use newkie's code at: http://www.codeproject.com/Articles/175030/PlaySound-A-Better-Way-to-Play-Wav-Files-in-C?msg=4366037#xx4366037xx
In my case, at least, I had to change all of the lowercase x's to uppercase x's, though, to get it to work.
I have hundreds of CSV files zipped. This is great because they take very little space but when it is time to use them, I have to make some space on my HD and unzip them before I can process. I was wondering if it is possible with .NET to unzip a file while reading it. In other words, I would like to open a zip file, start to decompress the file and as we go, process the file.
So there would be no need for extra space on my drive. Any ideas or suggestions?
Yes. Zip is a streamed format which means that you can use the data as you decompress it rather than having to decompress everything first.
With .net's System.IO.Compression classes you can apply similar compression as used in zip files (Deflate & GZip) to any stream you like, but if you want to work with actual zip format files you'll need a third party library like this one (sharpziplib).
A better solution might be to keep the files decompressed on the drive, but turn on compression on the file system level. This way you'll just be reading CSV files, and the OS will take care of making sure it doesn't take too much space.
Anyhoo, to answer your question, maybe the GZipStream class can help you.
sharpziplib allows for stream-based decompression - see this related question - the item provides similar stream-based Read methods, so you can process each item like you would with any stream.
I'm not sure about zip files, but you could use GZ format with GZipSteam (works like any other input stream). Unfortunately, the entire System.IO.Compression namespace is only 2 classes (the other does DEFLATE).
EDIT: There's a class called ZipPackage. I'm not sure how if it will let you do decompression streaming, but it might be worth looking into.
Also, take a look at #ziplib.
I am developing an application and I would like to be able to search the whole drive for a regular expression. I would prefer to do this in c# but I can call other languages. Is there any easy way to just seek through all the binary data on a drive from begining to end?
Here's an implementation of grep in C#
http://dotnet.jku.at/applications/Grep/Src.aspx
You can modify to follow subdirectories -- it works off of an array of filenames.
AFAIK there is no simple way to do this on raw binary data (You would need direct disk control).
If file-basis is enough enumerating all files, opening them for binary shared reading (catch the exceptions for the ones that are system protected) and then looking for the data should be straightforward. However this will be quite slow as enumerating and opening all files will take some time.
I don't think C# can read all files / data for the drive the OS is on, since the OS locks some files.
You could use the System.IO namespace to enumerate all files, and then scan them individually byte by byte, this obviously would take a long time.
Do you really want to do this ? How are you going to search:
.doc
.xls
.pdf
.html
etc.? Each file type will represent the string you're searching for in different ways.
This article shows how to read data directly from the disk. Everything they do from C++ could be done from C# using PInvoke.
I have a 10 second sound effect wave file. What I would like to do is take that file and repeat it n number of times and then save the longer WAV file to disk. This way I can create a much longer background effect rather than auto-repeat on the media player which is a bit stuttered between repeats. I am trying to do this in C#.
That's reasonably easy to do, given the WAV file format - assuming it's uncompressed audio (most WAV files are - or at least, they were last time I had anything to do with them).
There may well be audio APIs you can use to do this without getting stuck into the binary format, but I suspect they'd take as long to learn as just doing it yourself as you're not doing anything particularly complicated.
If you only need to do this with a small number of files, you might as well do it by hand with Audacity.
If you're using .Net 2.0 or higher then you can use the System.Media.SoundPlayer class and specifically its PlayLooping method to achieve what you want with no stuttering. This is preferable to creating a new wav file - it means less disk space for the file and less memory needed to render the sound. In general you should always use buffered techniques like this for audio playback if the sound will be looped or is longer than a few seconds.
You can do this easily in C# using the NAudio .NET audio library. You would need to use the WaveFileReader and WaveFileWriter classes. You can also use it to create a custom WaveStream that will loop your audio as many times as you want without the need to create a long WAV file.