When we decode a file, we can read a file with IContainer and after call container.readNextPacket(packet) >= 0, the packet can be filled. But how can I fill with the packet when I only get the H.264 Stream
I'm assuming you mean the H.264 stream is incoming, and you're wondering how to fill a packet with the data, correct?
In that case, you're doing it correctly. As long as you set up your IContainer to use the URL/Path of your H.264 stream, then container.readNextPacket(packet) will fill the IPacket with a packet of data from the H.264 stream.
Related
I'm looking for new solution to play h.264 steaming video ,which is based on 1722 protocol and entered in Ethernet from other device, in Windows 7 or 10 by using socket similarly with the way from linux environment.
I can bind network-interface directly using option of SO_BINDTODEVICE in linux and if I use that, video streaming is so smooth in vlc player and vlc statistics show bitrate is over 20,000 kb/s
so I tried two manners in Windows like below:
using scapy module in python
sniffing all raw packet Ethernet
attach data on payload and send packet to vlc player
result is poor, because the bitrate in vlc statistics is almost under 1500kb/s
using winpcap lib in C(VS)
sniffing all raw packet through pcap_next_ex or pcap_loop
attach data on payload and send packet to vlc player
result is bad, the bitrate in vlc statistics is 3000kb/s
1.
global dgramSock
dgramSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
def prn(pkt):
global dgramSock
...
#filter to pick specific packet
...
#attach data on payload and naming myPacket
...
send_len = dgramSock.sendto(myPacket, ('127.0.0.1', 44514))
sniff(prn = prn, filter='ether)
2.
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(44514);
...
while( (pcap_next_ex(_handle, &header, &pkt_data)) >=0){
...
#filter to pick specific packet
...
#attach data on payload and naming myPacket
...
sendto(sock, (char *)myPacket, myPacketSize, 0, (struct sockaddr *)&(addr), sizeof(addr));
}
I think that two manner what I tried looks not essential way.
In Windows, what is the best solution to send raw packet to other program fastly without loss?
I don't know exactly my solution is correct approach or not but I left my solution for one who seek some solution same problem like me
My wrong approach what I have been was using VLC in Windows.
I guess VLC listener buffer seem to small not enough to get all streaming data from socket, so streaming data looks corrupted or broken, even though little part of top in video played normal streaming.
So I tried new player, FFmpeg. FFmpeg provide ffplay.exe. It seems to decoder same with VLC.
I just send streaming data through UDP stack and valid port from Visual studio or Python. There is no issue using UDP socket, but you need to check listener buffer is enough to get all packets coming via network card.(like API: pcap_set_buffer_size)
If you can success to send your streaming data toward specific port what you want to send, next step is run ffplay with some command.
simple example command to run ffplay
ffplay.exe -codec:v h264 -i udp://127.0.0.1:44514 -framerate 30
Tip) For beginner in ffmpeg like me, you should keep order of command, ffplay and ffmpeg have strong rule of arguments, but simple rule is explained as input and output rule. You have to give input option first and output option come behind -i(input) option
There is many branch to using ffplay or to your environment so my explanation would not match correctly in many situations.
If I can answer your question, I will keep track on that.
Thank you
I'm sending an encoded live audio stream (mp3 or ogg) over websockets and i want to play it with the web audio api.
I read and tried several things but nothing worked so far...
I always tried to do it with the decodeAudioData Method.
But this method can not handle an continuous stream.
So my last approach was this:
ws.onmessage = function (evt) {
context.decodeAudioData(evt.data, function (decodedData) {
source = context.createBufferSource();
source.buffer = decodedData;
source.start(startTime);
source.connect(context.destination);
startTime += decodedData.duration;
},
function(e) {
var test = e;
}
);
};
This works at least with mp3s but not very well. between the received chunks there is a very small break. so there is no fluid playback of the stream. I don't know what's the reason for that... maybe the decodedData.duration property is not accuracte enough or there is some kind of delay anywhere.
Anyway it's not working at all with ogg files. I can hear the first received chunk but the rest is ignored. Maybe this has something to do with missing headers?
Is there any other method in the web audio api to play an encoded live stream then decodeAudioData? I could not find anything...
Thanks for your help!
Don't do this over web sockets if you can help it. Let the browser do its job and play this over HTTP. Otherwise you must reinvent everything.
If you insist on reinventing everything for some reason, you must:
Buffer incoming data
Decode that data
Buffer decoded data
Play back your decoded PCM buffers with a script node
Handle the times when you have buffer underruns/overruns (likely by playing back silence or dropping PCM samples)
How you do each of these items depends on your specific needs and implementation, so I would recommend splitting up the question if you get stuck on any of that.
I want to read IP packets from a non-blocking tun/tap file descriptor tunfd
I set the tunfd as non-blocking and register a READ_EV event for it in libevent.
when the event is triggered, I read the first 20 bytes first to get the IP header, and then
read the rest.
nr_bytes = read(tunfd, buf, 20);
...
ip_len = .... // here I get the IP length
....
nr_bytes = read(tunfd, buf+20, ip_len-20);
but for the read(tunfd, buf+20, ip_len-20)
I got EAGAIN error, actually there should be a full packet,
so there should be some bytes,
why I get such an error?
tunfd is not compatible with non-blocking mode or libevent?
thanks!
Reads and writes with TUN/TAP, much like reads and writes on datagram sockets, must be for complete packets. If you read into a buffer that is too small to fit a full packet, the buffer will be filled up and the rest of the packet will be discarded. For writes, if you write a partial packet, the driver will think it's a full packet and deliver the truncated packet through the tunnel device.
Therefore, when you read a TUN/TAP device, you must supply a buffer that is at least as large as the configured MTU on the tun or tap interface.
I am writing the callout driver for Hyper-V 2012 where I need to filter the packets sent from virtual machines.
I added filter at FWPM_LAYER_EGRESS_VSWITCH_TRANSPORT_V4 layer in WFP. Callout function receive packet buffer which I am typecasting it to NET_BUFFER_LIST. I am doing following to get the data pointer
pNetBuffer = NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket);
pContiguousData = NdisGetDataBuffer(pNetBuffer, NET_BUFFER_DATA_LENGTH(pNetBuffer), 0, 1, 0);
I have simple client-server application to test the packet data. Client is on VM and server is another machine. As I observed, data sent from client to server is truncated and some garbage value is added at the end. There is no issue for sending message from server to client. If I dont add this layer filter client-server works without any issue.
Callback function receives the metadata which incldues ipHeaderSize and transportHeaderSize. Both these values are zero. Are these correct values or should those be non-zero??
Can somebody help me to extract the data from packet in callout function and forward it safely to further layers?
Thank You.
These are the TCP packets. I looked into size and offset information. It seems the problem is consistent across packets.
I checked below values in (NET_BUFFER_LIST*)pClassifyData->pPacket.
NET_BUFFER_LIST->NetBUfferListHeader->NetBUfferListData->FirstNetBuffer->NetBuffe rHeader->NetBufferData->CurrentMdl->MappedSystemVa
First 24 bytes are only sent correctly and remaining are garbage.
For example total size of the packet is 0x36 + 0x18 = 0x4E I don't know what is there in first 0x36 bytes which is constant for all the packets. Is it a TCP/IP header? Second part 0x18 is the actual data which i sent.
I even tried with API NdisQueryMdl() to retrieve from MDL list.
So on the receiver side I get only 24 bytes correct and remaining is the garbage. How to read the full buffer from NET_BUFFER_LIST?
I am looking to extract the Song name from an ice cast streaming radio. I am getting the icy-genre,icy-name n stuff. but not the song name. Can we extract it from the stream?
From your question I presume you already added Icy-Metadata: 1 to you request.
You'll have to read the "icy-metaint" response header, that will tell you how bytes to read between each metadata update in the stream.
The following is pseudocode:
byteinterval = int(response.getHeader("icy-metaint"))
stream = response.getBodyStream()
stream.read(byteinterval)
metadata_len = byte(stream.read(1)) * 16
metadata = stream.read(metadata_len)
The metadata will look something like this:
StreamTitle='Some Song Name Stream Client Sent';StreamUrl='http://someurl.com/';
Unfortunately there's no absolute standard for either encoding of the complete metadata buffer, or the contents of the StreamTitle.
Song name may or may not contain album name, artist name and complete song name or other fields.
The metadata buffer itself may or may not be UTF-8. It's up to the streaming client to decide on what to inject. Most decent clients will use UTF-8 when forced to send non ASCII data, but not all (and they may send some native encoding like Windows-1521 or UTF-16).
If you want to keep getting metadata updates you can simply consume blocks of "byteinterval" length of bytes to get more metadata updates, or disconnect and poll the stream later.