问题
I have video in Azure blob container. I opened the connection using proxy and get the inputStream from the connection and passing to Xuggler.
HttpURLConnection conn = null;
boolean isUseProxyConnection = proxyFileValues.isUseProxyConnection();
// Use Proxy
if (isUseProxyConnection) {
proxy = AzureBlobStorageProxyConnection();
}
URL urlPath = new URL(inputFile);
if (isUseProxyConnection) {
// Open Via Proxy
conn = (HttpURLConnection) urlPath.openConnection(proxy);
} else {
// Open without Proxy
conn = (HttpURLConnection) urlPath.openConnection();
}
String urlofFrame = urlPath.getPath();
System.out.println("urlofFrame" + urlofFrame);
// Connect via Proxy or without Proxy
conn.connect();
int status = conn.getResponseCode();
InputStream input = null;
BufferedImage buffimage = null;
if (status == HttpURLConnection.HTTP_OK) {
input = conn.getInputStream();
System.out.println("input URL :" + conn.getURL());
if (urlofFrame.endsWith(".avi")) {
LOG.debug("AVI Video File");
AVIFileHandler av = new AVIFileHandler();
buffimage = av.bufferedImageToBlob(input, taskNumber);
} }
Now i am trying to open video container and get the buffered Image
public BufferedImage bufferedImageToBlob(InputStream inputStream, int FrameNumber) {
//InputStream iStream = inputStream;
int frameNumber = FrameNumber + 1;
BufferedImage bufferedImage = null;
LOG.debug("Video frameNumber: " + frameNumber);
boolean imageValue = false;
IContainer container = IContainer.make();
int streamOpen = 0;
streamOpen = container.open(inputStream, container.getContainerFormat());
System.out.println("Opened : " + container.isOpened());
if (streamOpen < 0)
throw new IllegalArgumentException("could not open file: " + container.getURL());
// query how many streams the call to open found
int numStreams = container.getNumStreams();
// and iterate through the streams to find the first video stream
int videoStreamId = -1;
//allows you to decode or encode that data.
IStreamCoder videoCoder = null;
for (int i = 0; i < numStreams; i++) {
// Find the stream object
IStream stream = container.getStream(i);
// Get the pre-configured decoder that can decode this stream;
IStreamCoder coder = stream.getStreamCoder();
if (coder.getCodecType() == Type.CODEC_TYPE_VIDEO) {
videoStreamId = i;
videoCoder = coder;
break;
}
}
if (videoStreamId == -1)
LOG.error("could not find video stream in container: " + container.getURL());
if (videoCoder.open() < 0)
LOG.error("could not open video decoder for container: " + container.getURL());
IVideoResampler resampler = null;
if (videoCoder.getPixelType() != IPixelFormat.Type.BGR24) {
// if this stream is not in BGR24, we're going to need to
// convert it. The VideoResampler does that for us.
resampler = IVideoResampler.make(videoCoder.getWidth(), videoCoder.getHeight(), IPixelFormat.Type.BGR24,
videoCoder.getWidth(), videoCoder.getHeight(), videoCoder.getPixelType());
if (resampler == null)
throw new RuntimeException("could not create color space " + "resampler for: " + container.getURL());
}
//Seek Frame ******Not working
**container.seekKeyFrame(0, frameNumber, IContainer.SEEK_FLAG_FRAME);**
LOG.info("Blob Video Frame Height: " + resampler.getInputHeight());
LOG.info("Blob Video Frame Width: " + resampler.getInputWidth());
LOG.info("Blob Video Codec_ID: " + videoCoder.getCodecID());
IPacket packet = IPacket.make();
while (container.readNextPacket(packet) >= 0) {
/*
* Now we have a packet, let's see if it belongs to our video stream
*/
if (packet.getStreamIndex() == videoStreamId) {
IVideoPicture picture = IVideoPicture.make(videoCoder.getPixelType(), videoCoder.getWidth(),
videoCoder.getHeight());
int offset = 0;
while (offset < packet.getSize()) {
/*
* Now, we decode the video, checking for any errors.
*/
int bytesDecoded = videoCoder.decodeVideo(picture, packet, offset);
if (bytesDecoded < 0)
LOG.error("got error decoding video in: " + container.getURL());
offset += bytesDecoded;
/*
* Some decoders will consume data in a packet, but will not be able to
* construct a full video picture yet. Therefore you should always check if you
* got a complete picture from the decoder
*/
if (picture.isComplete()) {
System.out.println("Frame Numer" + frameNumber);
IVideoPicture newPic = picture;
/*
* If the resampler is not null, that means we didn't get the video in BGR24
* format and need to convert it into BGR24 format.
*/
if (resampler != null) {
// we must resample
newPic = IVideoPicture.make(resampler.getOutputPixelFormat(), picture.getWidth(),
picture.getHeight());
if (resampler.resample(newPic, picture) < 0)
LOG.error("could not resample video from: " + container.getURL());
}
if (newPic.getPixelType() != IPixelFormat.Type.BGR24)
LOG.error(
"could not decode video" + " as BGR 24 bit data in: " + container.getURL());
frameCounter++;
bufferedImage = Utils.videoPictureToImage(newPic);
}
}
// Break the Loop if image found
if (imageValue == true) {
break;
}
} else {
/*
* This packet isn't part of our video stream, so we just silently drop it.
*/
do {
} while (false);
}
}
return bufferedImage;
}
If the video is in file system, seekFrame can forward the video and get the frame where as for inputStream seekFrame is not forwarding the video (it always gives me first frame).
Any help would be appreciated. Thanks in advance
来源:https://stackoverflow.com/questions/58483424/error-while-opening-video-file-from-url-and-seekframe-not-working-xuggler