c++ ffmpeg api get video stream from https link - c++

I'm trying to read https video link using the function av_format_open_input() but the function return a negative value.
Here is my code:
av_register_all();
avcodec_register_all();
avformat_network_init();
const char * url = "https://r1---sn ...";
AVFormatContext * pFormatCtx = avformat_alloc_context();
int ret = avformat_open_input(&pFormatCtx, url, NULL, NULL);
This code worked with a local file as url but as soon as I give a https url it doesnt work anymore.
thanks
[edit]
I found only this: ffserver.c
But it uses a .ffm file as input. Any exemple or help on how to implement HttpContext (if HttpContext is needed here) would be great.
[update]
I ended using libvlc which seems to be much easier but the way to do it using ffmpeg could still be interesting. See my other post if interested: Get frame from video with libvlc smem and convert it to opencv Mat. (c++)

Related

C++ LibVLC broadcast audio

Before creating the post I was looking but I can't find a solution to my problem.
I am trying to broadcast my microphone's default output live.
If you paste in the cmd replacing the ip, it will start transmitting sound from your microphone.
"C:\Program Files\VideoLAN\VLC\vlc.exe" --qt-start-minimized dshow:// :dshow-vdev=none :dshow-adev= :sout=#transcode{vcodec=none,acodec=mp3,ab=128}:standard{access=http,mux=mp3,dst=192.168.1.253:8080}
So I decided to move that command from cmd to c ++
std::cout<<"BEGIN BROADCAST"<<std::endl;
libvlc_instance_t *vlc;
const char *url = "dshow://";
const char *sout = "#transcode{vcodec=none,acodec=mp3,ab=128}:http{mux=mp3,dst=192.168.1.253:8080}";
const char *media_name = "Radio";
vlc = libvlc_new(0, NULL);
std::cout<< libvlc_vlm_add_broadcast(vlc, media_name, url, sout, 0, NULL, true, false);
std::cout<<"END BROADCAST"<<std::endl;
According to the official documentation, it returns an int if the transmission was successful -> int libvlc_vlm_add_broadcast
https://videolan.videolan.me/vlc-3.0/group__libvlc__vlm.html#gaa8d58569f07229edabe9fdaab41b1c3d
It returns 0 to me.
But when I open another VLC to access: http://192.168.1.253:8080 it won't connect ...
Is there someone who can help me? I really appreciate it, greetings.
One of the posts that comes closest is this:
Use libvlc to stream mp3 to network

How to get format of video stream in ffmpeg (c++)

I have a function that reads frames from a stream. I want to find out what the format of the stream is (I'm testing with H264):
StreamingResult MediaWriter::Open(const AVFormatContext *const inputFormatContext,
const fs::path &destination)
{
// Save input stream data
AVStream *videoStream = inputFormatContext->streams[FindVideoStreamIndex(inputFormatContext)];
//....
}
How can I get the format/codec type from the video stream? I am expecting to receive H264, but other formats will be received in the future.
P.S.: Some good FFMPEG documentation would be appreciated, because I am getting lost in Doxygen generated documentation.
Some good FFMPEG documentation would be appreciated, because I am getting lost in Doxygen generated documentation.
Doxygen is th best ffmpeg documentation there is. Its just ffmpeg is a very large peroject and takes time to learn.
What you are looking for is videoStream->codecpar->codec_id

h264 encode video stream ffmpeg c++

I'm trying to develop A live streaming app that capture video from web cam encode it to H264 video stream and use rtsp to send it to device,
I've looked up some examples and found this:
FFMPEG to send RTSP encoded stream C++
I've been using it as a reference to my program.
However I'm keep getting AVCodec type "MPEG", I've been trying to change filename extension and tried different approaches with avformat_alloc_output_context2
This is the relevant code:
const char *filename = "rtsp://127.0.0.1:7003/live.sdp";
AVOutputFormat *fmt;
AVFormatContext *oc;
AVStream *video_st;
AVCodec *video_codec;
video_st = NULL;
av_register_all();
avformat_network_init();
// format context:
avformat_alloc_output_context2(&oc,NULL,"rtsp",filename);
After calling avformat_alloc_output_context2 oc->oformat->video_codec is generated as MPEG codec.
I've tried changing filename extension to:
const char *filename = "rtsp://127.0.0.1:7003/live.264";
const char *filename = "rtsp://127.0.0.1:7003/live.h264";
and a bunch of other extensions.
How can I generate a H264 stream?
According to the documentation, you need to pass an output format to avformat_alloc_output_context2.
To quote (content in square brackets mine):
[the second parameter is the] format to use for allocating the context, if NULL format_name and filename are used instead
This parameter is a pointer to type AVOutputFormat.
Alternatively, you could continue to pass NULL and infer the output by using H264 as the format name.
Either way, I think you'll need to separate the encoding process from the streaming protocol.
This separation of concerns is useful, as if you find you want to use a different protocol to get the stream, the encoding code does not need to know about it.

How to use ffmpeg faststart flag programmatically?

I try to convert videos for playback on Android using H264, AAC codecs and mp4 container. Video plays normaly with non-system players. But system player shows error "Can't play this video".
I found out that the problem is in moov atom, which is writed in the end of the file.
When I use "-movflags +faststart" ffmeg flag to convert video, it plays normal, but when I try to do that programmatically, it gives no result. I use following code:
av_dict_set( &dict, "movflags", "faststart", 0 );
ret = avformat_write_header( ofmt_ctx, &dict );
This code works fine:
av_dict_set( &dict, "movflags", "faststart", 0 );
ret = avformat_write_header( ofmt_ctx, &dict );
But problem is not solved. I still can't play converted videos on Android devices.
I assume that this answer is very late, but still, for anyone who might still be facing the same issue: this might be caused by the AV_CODEC_FLAG_GLOBAL_HEADER not being set in the audio/video AVCodecContext. A lot of guides show that it needs to be set in the AVFormatContext, but it needs to be set in the AVCodecContext before opening it using avcodec_open2.
if (format_context->oformat->flags & AVFMT_GLOBALHEADER) {
video_codec_context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
}
avcodec_open2(video_codec_context, video_codec, nullptr);
Maybe the video is not compatible with your android phone? Try to convert with h264 baseline profile.
TL;DR
Set url field of AVFormatContext before avformat_write_header.
Why
I hit same issue today, and I found there is a log when calling av_write_trailer:
Unable to re-open output file for the second pass (faststart)
In the movenc.c implementation, we can see it needs s->url to re-open the file:
avio_flush(s->pb);
ret = s->io_open(s, &read_pb, s->url, AVIO_FLAG_READ, NULL);
if (ret < 0) {
av_log(s, AV_LOG_ERROR, "Unable to re-open %s output file for "
"the second pass (faststart)\n", s->url);
goto end;
}

Unable to get Video feed from D-Link DCS 932L using openCv

I am trying to display video feed from IP- Camera(D-Link DCS 932L). I Have gone through topics for the same and tried the code from different posts, but am unable to get the video feed from the camera.
Here's the code which i tried.
#include <opencv/cv.h>
#include <opencv/highgui.h>
using namespace cv;
int main(int argc, char *argv[])
{
Mat frame;
namedWindow("video", 1);
String url = "http://admin:admin#172.32.20.55:80/image/jpeg.cgi";
VideoCapture cap(url);
/* VideoCapture cap(0);*/
while ( cap.isOpened() )
{
cap >> frame;
if(frame.empty()) break;
imshow("video", frame);
if(waitKey(30) >= 0) break;
}
return 0;
}
I tried many different kind of url's but i was unable to display any video feed. I thought it might be code problem so I even tried displaying the USB Webcam and it worked. So now i come to conclusion that the problem seems to be with URL which am passing. Heres the list of urls which I tried. I got this Url options from iSpy.Here are those URL's
(JPEG)http://admin:admin#172.32.20.55:80?IMAGE.JPG
(JPEG)http://admin:admin#172.32.20.55:80/image/jpeg.cgi
(MPEG)http://admin:admin172.32.20.55:80/video.cgi?resolution=VGA
(MPEG)http://admin:admin172.32.20.55:80/video/mjpg.cgi
(MPEG)http://admin:admin172.32.20.55:80/mjpeg.cgi? user=admin&password=admin&channel=0
(MPEG)http://admin:pnqadmin172.32.20.55:80/VIDEO.CGI
Please let me know what can be probable problem for displaying the video feed.
Is their something to do with the setting of the OpenCv or something else.Please note that am using VS2010 and C++ Need help of all the Expert out their.
Thanks in advance.
I solved my problem. The problem was with URL. I changed the URL and it worked smooth..!
The URL i used was as follows.
"http://USER:PWD#IPADDRESS:8088/mjpeg.cgi?user=USERNAME&password=PWD&channel=0&.mjpg";
I keep getting the same error:
warning: Error opening file <../../modules/highgui/src/cap_ffmpeg_impl.hpp:529>
I was trying to stream MJPG video from a Foscam IP camera. The URL opened just fine but I couldn't read any frames. May be there was some problem with the video codec.
Here's a hack written in Python that worked for me: https://stackoverflow.com/a/18411168/3183051
Perhaps my answer is too late. Check if opencv_ffmpegXXX.dll or opencv_ffmpegXXX_64.dll (if you are building 64bit executable) is in the same folder where your executable is. Replace XXX with the number of opencv version you use.