First of all, I hope you'll understand my poor english skill. I'll do my best to write question about it.
I'm currently developing some application. That application will captures desktop and encodes to MP4 video and send mp4 video data/chunks to another clients (all this process should run in memory not file). so another client should can play mp4 video/data/chunks that received from server.
so I used avio = avio_open(...) and reassigned write function as like avio->write_packet = some_function. but this way seems not "generate" mp4 file/chunk correctly. and It seems the original write_packet callback having actual logic that write packet to a file. but I don't want to write to a file. so I was thinking about it for a week but I did't getting any of idea about it.
so my question is: How can I intercept "encoded" video data that should processed by avio->write_packet?
Don't hijack avio_open-provided aviocontext, that's bound to cause you troubles. If you want to provide custom AVIOContext, do so - use avio_alloc_context and provide your callbacks there. Use flag AVFMT_FLAG_CUSTOM_IO to indicate that you did so (so this AVIOcontext won't be destroyed automatically when muxer closes).
Related
I wrote two command line applications in C++ which use WebRTC:
Client creates a PeerConnection and opens an AudioStream
Server receives and plays the AudioStream
The basic implementation works: They exchange SDP-Offer and -Answer, find their external IPs using ICE, a PeerConnection and a PeerConnectionFactory with the corresponding constraints are created, etc. I added a hook on the server side to RtpReceiverImpl::IncomingRtpPacket which writes the received payload to a file. The file contains valid PCM audio. Therefore, I assume the client streams data successfully through the network to the server application.
On the server side, my callback PeerConnectionObserver::OnAddStream is called and receives a MediaStreamInterface. Furthermore, i can iterate with my DeviceManagerInterface::GetAudioOutputDevices through my audio devices. So basically, everything is fine.
What is missing: I need some kind of glue to tell WebRTC to play my AudioStream on the corresponding device. I have seen that I can get an AudioSink, AudioRenderer and AudioTrack objects. Again: Unfortunatly, I do not see an interface to pass them to the audio device. Can anyone help me with that?
One important note: I want to avoid to debug real hardware. Therefore, I added -DWEBRTC_DUMMY_FILE_DEVICES when building my WebRTC modules. It should write audio to an output file but the file just contains 0x00. The input file is read successfully because as I mentioned earlier, audio is send via RTP.
Finally, I found the solution: First, I have to say that my Code uses a WebRTC from 2017. So, the following things may have been changed and/or are fixed already:
After debugging my code and the WebRTC library I saw: When a remote stream is added, playback should start automatically. There is no need on the developer side to call playout() in the VoiceEngine or something comparable. When the library recognizes a remote audio stream, playback is paused, the new source is added to the mixer, and playback is resumed. The only APIs to control playback are provided by webrtc::MediaStreamInterface which is passed via the PeerConnectionObserver::OnAddStream. Examples are SetVolume() or set_enabled().
So, what went wrong in my case? I used the FileAudioDevice class which should write raw audio data to an output file instead of speakers. My implementation contains two bugs:
FileAudioDevice::Playing() returned true in any case. Due to this, the library added the remote stream, wanted to resume playout, called FileAudioDevice::Playing() which returned true and aborted because it thought the AudioDevice was already in playout mode.
There seems to be a bug in the FileWrapper class. The final output is written in FileAudioDevice::PlayThreadProcess() via _outputFile.Write(_playoutBuffer, kPlayoutBufferSize) onto disk. However, this does not work. Luckily, a plain C fwrite() as hacky bugfix does work.
Looking through all the API documentation, I can see how one could create procedural audio, but once an audio file is created, I want it to play on an object, but from I can tell, I believe I need it to play using the function calls PlayEventAtLocation in the UE4 plugin, which means I need to get the sound into an event.
I used to have my setup in Unity 4.x. I want to dynamically construct a wav file in game and play it back. The idea was to have silent audio all over the map that would loop, but play muted. The player when in range would capture audio from this muted audio source at their discretion.
The idea is that you have wav file that plays in game and at any given time I can start grabbing data from where the buffer is at currently until I decide to stop. I take all the data that I created in this new buffer and create a new wav file with it.
Example, like a 20 second file, but I would grab the a 7 second audio clip starting 5 seconds in. So my new audio file would be from 5 to 12. I would think you could do similar things in FMOD because I’ve looked at the recording examples and gapless playback examples, etc. and it does seem to have that same functionality and access to seek the files.
Now I need to migrate this new file that will made in game to something UE4 would use. In FMOD, looking through the .h and .cpp files in the plugin files, I see accept Fmod events only to attach to a UObject. Since I've not made an event in FMOD Studio, I can't use these. What is the sound that createSound makes? is it a wav? and fsb? I just a have a sound, and don't know what format it is.
I can’t use designer to make this sound because its dependent on the player at any given time during play.
In Unity, what I did was access the buffer of an audio file, pull data from the buffer for any given time, and place in a new buffer that I then turned into a file. While pulling data, I would check buffer size and frequency of sound files to make sure I had a gapless playback. (Not perfect, but pretty darn close), I’d use the audio functions in Unity to convert my array of data into a useable audioclip and run it through a sound emitter. It was pretty nice. Because I would keep the original wav file muted, but looping. So the player never knew what they captured. It was really nice.
Since UE4 doesn’t allow access to uncompressed PCM data, I can't do this low level data manipulation in UE4. I had to use FMOD, but its proving to be just as difficult because either its not documented, or lacks the functionality I want. I need help please.
If the data that is created in createsound is just normal pcm wav file data, then I can use a standard AudioComponent, and just save it to a file, and pull it in from UE4. If it is, then I need to turn it into an event so I can use FMODPlayEventAttached from the FMOD plugin library.
I've made a few other posts in various locations that have all been silent. Any comment would be appreciated. I know I've been reading a lot of documentation these last few days on FMOD, but I still may have missed something if people want to point me in a better direction, or if you have something to add, feel free.
Thanks all. I hope I was descriptive enough.
We have a requirement to lets users record a video of our 3D application. I can already grab the individual rendered frames so this question is specifically about how to write frames into a video file.
I don't think writing each frame as a separate file and post-processing is a workable option.
I can look at options to record to a simple video file for later optimising/encoding, or writing directly to a sensibly encoded format.
FFmpeg was suggested in another post but it looks a bit daunting to me. Is it the best option, if not what can be suggested? We can work with LGPL but not full GPL.
We're working on Windows (Win32 not MFC) in C++. Sample/pseudo code with your recommended library is very much appreciated... basically after how to do 3 functions:
startRecording() does whatever initialization is needed
recordFrame() takes pointer to frame data and encodes it, ideally with timing data
endRecording() finalizes the video file, shuts down video system, etc
Check out the sources to Taksi on sourceforge. http://taksi.sourceforge.net/
You need 2 things.
1. A code to compress the frames.
2. A container file format. Like AVI or MPG.
Taksi useses the old VideoForWindows API and AVI not the newer COM API's but it still might work for you.
In my application we will present the video stream from a traffic camera to a client viewer. (And eventually several client viewers.) The client should have the ability to watch the live video or rewind the video and watch earlier footage including video that occurred prior to connecting with the video stream. We intend to use wxWidgets to view the video and within that we will probably use the wxMediaCtrl.
Now, from the above statements some of you might be thinking "Hey, he doesn't know what he's talking about." And you would be correct! I'm new to these concepts and I confused by the surplus of information. Are the statements above reasonable? Can anyone recommend a basic server/client architecture for this? We will definitely be using C++ wxWidgets for the GUI, but perhaps wxMediaCtrl is not what I want... should I be directly using something like the ffmpeg libraries?
Our current method seems less than optimal. The server extracts a bitmap from each video frame and then waits for the single client to send a "next frame" message, at which point the server sends the bitmap. Effectively we've recreated our own awkward, non-standard, inefficient, and low-functionality video streaming protocol and viewer. There has to be something better!
You should check out this C++ RTMP Server: http://www.rtmpd.com/. I quickly downloaded, compiled and successfully tested it without any real problems (on Ubuntu Maverick). The documentation is pretty good if a little all over the place. I suspect that once you have a streaming media server capable of supporting the typical protocols (which rtmpd seems to do), then writing a client should fall into place naturally, especially if you're using wxWidgets as the interface api. Of course, it's easy to write that here, from the comfort of my living room, it'll be a different story when you're knee deep in code :)
you can modify your software such that:
The server connect, server grabs an image, passes it to ffmpeg establishing stream, then copy the encoded data from ffmpeg stream and send to client via network, if the connection drops, close the ffmpeg stream.
Maybe you can use the following to your own advantage:
http://www.kirsle.net/blog.html?u=kirsle&id=63
There is a player called VLC. It has a library for c++ and you can use it to embed the player in your GUI application. It supports a very wide range of protocols. So you should leave connecting, retrieving and playing jobs to VLC and take care of the starting and stopping jobs only. It would be easy and probably a better solution than doing it yourself.
For media playing facility, both music and audio, you can a look on GStream. And talking about the server, I think Twisted (A network library in Python) should be good option. The famous live video social website justin.tv is based on Twisted. Here you can read the story from here. Also, I built a group of server for streaming audio on Twisted, too. They can serve thousands of listener on line in same time.
I have an application that grabs video from multiple webcams, does some image processing, and displays the result on the screen. I'd like to be able to stream the video output on to the web - preferably to some kind of distribution service rather than connecting to clients directly myself.
So my questions are:
Do such streaming distribution services exist? I'm thinking of something like ShoutCAST relays, but for video. I'm aware of ustream.tv, but I think they just take a direct webcam connection rather than allow you to send any stream.
If so, is there a standard protocol for doing this?
If so, is there a free library implementation of this protocol for Win32?
Ideally I'd just like to throw a frame of video in DIB format at a SendToServer(bitmap) function, and have it compress, send, and distribute it for me ;)
Take a look at video LAN client (or VLC for short) as a means for streaming video.
As for distribution sites, I don't know how well it works with ustream.tv and similar new services.
ustream.tv works by using Adobe Flash's support for reading input from a webcam. To fake it out, you need a fake webcam driver. Looking on the ustream.tv site, they point to an application called WebCamMax that allows effects and splicing in video. It works by creating a pseudo-webcam that mixes video from one or more cameras along with other sources. Since that app can do it, your own code could do that too, although you'll probably need to write a Windows driver to get it all working correctly.