{"id":1127,"date":"2010-05-13T08:15:48","date_gmt":"2010-05-13T06:15:48","guid":{"rendered":"https:\/\/alax.info\/blog\/?p=1127"},"modified":"2016-10-17T14:56:43","modified_gmt":"2016-10-17T12:56:43","slug":"mediatools-two-samples-to-capture-m-jpeg-video-into-jpeg-files-and-to-play-jpeg-files-back","status":"publish","type":"post","link":"https:\/\/alax.info\/blog\/1127","title":{"rendered":"MediaTools: Two samples to capture M-JPEG video into JPEG files and to play JPEG files back"},"content":{"rendered":"<p>I added two new simple samples for the MediaTools DirectShow filters to demonstrate how to capture M-JPEG video feed, esp. from an IP camera, and write the video frames into sequence of JPEG files. The other sample takes a directory on the input and plays the images back as video. If you are working on certain transformation filter, it is an easy way to make a reference feed and use it for debugging purposes.<\/p>\n<p>The filters behind that empower the sample are described in <a href=\"https:\/\/alax.info\/blog\/741\">another post<\/a>.<\/p>\n<p><strong>RenderHttpMjpegVideoIntoFiles01<\/strong> sample takes an URL on the input to generate <a href=\"http:\/\/www.whoishostingthis.com\/resources\/mime-types\/\">image\/jpeg JPEG<\/a> or <a href=\"http:\/\/en.wikipedia.org\/wiki\/Motion_JPEG\">multipart\/x-mixed-replace M-JPEG<\/a> stream. For example, it might be <a href=\"http:\/\/demo1.stardotcams.com\/nph-mjpeg.cgi\">http:\/\/demo1.stardotcams.com\/nph-mjpeg.cgi<\/a> feed from a demo <a href=\"http:\/\/www.stardot.com\/\">StarDot Technologies<\/a> IP camera.<\/p>\n<p>The application will create a new directory to write files into, and will save each new video frame received into new JPEG file.<\/p>\n<pre>Z:\\MediaTools\\Samples\\RenderHttpMjpegVideoIntoFiles01\\Release&gt;RenderHttpMjpegVideoIntoFiles01.exe http:\/\/demo1.stardotcams.com\/nph-mjpeg.cgi\r\nURL: http:\/\/demo1.stardotcams.com\/nph-mjpeg.cgi\r\nWriting to directory: Z:\\MediaTools\\Samples\\RenderHttpMjpegVideoIntoFiles01\\Release\\2010-05-12 22-07-37\r\nEvent: nCode EC_CLOCK_CHANGED 0xD, nParameter1 0x00000000, nParameter2 0x00000000\r\nEvent: nCode EC_PAUSED 0xE, nResult 0x00000000, nParameter2 0x00000000\r\n[...]\r\n^C<\/pre>\n<p>The application will generate the files and convert media sample time stamps into file time.<\/p>\n<p><a href=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2010\/05\/13-Image001.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-1128\" title=\"RenderHttpMjpegVideoIntoFiles01 Sample Output\" src=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2010\/05\/13-Image001-320x175.png\" alt=\"RenderHttpMjpegVideoIntoFiles01 Sample Output\" width=\"320\" height=\"175\" srcset=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2010\/05\/13-Image001-320x175.png 320w, https:\/\/alax.info\/blog\/wp-content\/uploads\/2010\/05\/13-Image001-800x438.png 800w, https:\/\/alax.info\/blog\/wp-content\/uploads\/2010\/05\/13-Image001.png 994w\" sizes=\"auto, (max-width: 320px) 100vw, 320px\" \/><\/a><\/p>\n<p>The DirectShow graph that implements the operation is the following:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1129\" title=\"RenderHttpMjpegVideoIntoFiles01 Filter Graph\" src=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2010\/05\/13-Image002.png\" alt=\"RenderHttpMjpegVideoIntoFiles01 Filter Graph\" width=\"661\" height=\"346\" srcset=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2010\/05\/13-Image002.png 661w, https:\/\/alax.info\/blog\/wp-content\/uploads\/2010\/05\/13-Image002-320x167.png 320w\" sizes=\"auto, (max-width: 661px) 100vw, 661px\" \/><\/p>\n<p>The other sample <strong>RenderJpegFiles01<\/strong> takes a directory path to look for JPEG files, e.g. generated by previous sample, and pushes them into DirectShow graph as a video feed. File times will be converted [back] to media sample times.<\/p>\n<p><!--more--><\/p>\n<pre>Z:\\MediaTools\\Samples\\RenderJpegFiles01\\Release&gt;RenderJpegFiles01 \"Z:\\MediaTools\\Samples\\RenderHttpMjpegVideoIntoFiles01\\Release\\2010-05-12 22-07-37\"\r\nDirectory: Z:\\MediaTools\\Samples\\RenderHttpMjpegVideoIntoFiles01\\Release\\2010-05-12 22-07-37\r\nEvent: nCode EC_CLOCK_CHANGED 0xD, nParameter1 0x00000000, nParameter2 0x00000000\r\nEvent: nCode EC_PAUSED 0xE, nResult 0x00000000, nParameter2 0x00000000\r\nEvent: nCode EC_VMR_RECONNECTION_FAILED 0x55, nResult 0x80004005, nParameter2 0x00000000\r\nEvent: nCode EC_VMR_RENDERDEVICE_SET 0x53, RendererDeviceType 0x2, nParameter2 0x00000000\r\nEvent: nCode EC_VIDEO_SIZE_CHANGED 0xA, Extent 384x240, nParameter2 0x00000000\r\nEvent: nCode EC_COMPLETE 0x1, nResult 0x00000000, nParameter2 0x00000000\r\nEvent: nCode EC_ERRORABORT 0x3, nResult 0x80004005, nParameter2 0x00000000\r\nDetected resolution change, new resolution is 1024x768, recreating filter graph...\r\nEvent: nCode EC_VMR_RECONNECTION_FAILED 0x55, nResult 0x80004005, nParameter2 0x00000000\r\nEvent: nCode EC_VMR_RENDERDEVICE_SET 0x53, RendererDeviceType 0x2, nParameter2 0x00000000\r\nEvent: nCode EC_VIDEO_SIZE_CHANGED 0xA, Extent 384x240, nParameter2 0x00000000\r\nEvent: nCode EC_CLOCK_CHANGED 0xD, nParameter1 0x00000000, nParameter2 0x00000000\r\nEvent: nCode EC_PAUSED 0xE, nResult 0x00000000, nParameter2 0x00000000<\/pre>\n<p><a href=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2010\/05\/13-Image003.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-1130\" title=\"RenderJpegFiles01 DirectShow Graph and Output\" src=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2010\/05\/13-Image003-312x320.png\" alt=\"RenderJpegFiles01 DirectShow Graph and Output\" width=\"312\" height=\"320\" srcset=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2010\/05\/13-Image003-312x320.png 312w, https:\/\/alax.info\/blog\/wp-content\/uploads\/2010\/05\/13-Image003-585x600.png 585w, https:\/\/alax.info\/blog\/wp-content\/uploads\/2010\/05\/13-Image003.png 741w\" sizes=\"auto, (max-width: 312px) 100vw, 312px\" \/><\/a><\/p>\n<p>Download links:<\/p>\n<ul>\n<li>RenderHttpMjpegVideoIntoFiles01: <a href=\"http:\/\/www.assembla.com\/code\/roatl-utilities\/subversion\/nodes\/trunk\/MediaTools\/Samples\/RenderHttpMjpegVideoIntoFiles01\">source code<\/a>, <a href=\"http:\/\/www.assembla.com\/code\/roatl-utilities\/subversion\/nodes\/trunk\/MediaTools\/Samples\/RenderHttpMjpegVideoIntoFiles01\/Release\/RenderHttpMjpegVideoIntoFiles01.exe?format=raw\">binary<\/a><\/li>\n<li>RenderJpegFiles01: <a href=\"http:\/\/www.assembla.com\/code\/roatl-utilities\/subversion\/nodes\/trunk\/MediaTools\/Samples\/RenderJpegFiles01\">source code<\/a>, <a href=\"http:\/\/www.assembla.com\/code\/roatl-utilities\/subversion\/nodes\/trunk\/MediaTools\/Samples\/RenderJpegFiles01\/Release\/RenderJpegFiles01.exe?format=raw\">binary<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>I added two new simple samples for the MediaTools DirectShow filters to demonstrate how to capture M-JPEG video feed, esp. from an IP camera, and write the video frames into sequence of JPEG files. The other sample takes a directory on the input and plays the images back as video. If you are working on&hellip; <\/p>\n<p><a class=\"moretag\" href=\"https:\/\/alax.info\/blog\/1127\">Read the full article<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11,159,13],"tags":[38,78,294,75,158,492,137,488,486],"class_list":["post-1127","post","type-post","status-publish","format-standard","hentry","category-atl","category-media-tools","category-source","tag-c","tag-directshow","tag-ip-camera","tag-jpeg","tag-m-jpeg","tag-media-tools","tag-sample","tag-source","tag-video"],"_links":{"self":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts\/1127","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/comments?post=1127"}],"version-history":[{"count":0,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts\/1127\/revisions"}],"wp:attachment":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/media?parent=1127"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/categories?post=1127"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/tags?post=1127"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}