Задача: Работа с камерой
Исходник: Сохранение MJPEG с камеры Panasonic BB-HCM531A, язык: perl [code #584, hits: 12080]
автор: - [добавлен: 09.02.2009]
  1. #!/usr/bin/perl -w
  2. use Net::HTTP;
  3. use Getopt::Std;
  4. use MIME::Base64;
  5.  
  6. our ($opt_f, $opt_u, $opt_p, $opt_i);
  7. getopts('f:u:p:i:');
  8.  
  9. die 'please specify -f "folder_name" -u "userName" -p "Password" -i "CameraIpAddress' unless($opt_f && $opt_u && $opt_p && $opt_i);
  10.  
  11. # todo add custom directory support
  12. $current_video_archive_directory = $opt_f;
  13.  
  14. $authorization_parameter = encode_base64($opt_u . ':' . $opt_p);
  15.  
  16. # change currentdirectory
  17. chdir $current_video_archive_directory or
  18. do
  19. {
  20. # looks like we should create archive dir
  21. mkdir $current_video_archive_directory or die "we cannot create directory $current_video_archive_directory";
  22. chdir $current_video_archive_directory or die "we cannot use directory $current_video_archive_directory as file archive directory";
  23. };
  24.  
  25.  
  26. my $s = Net::HTTP->new(Host => $opt_i) || die $@;
  27.  
  28. $s->write_request('GET' => "/nphMotionJpeg?Resolution=640x480&Quality=Standard",
  29. 'User-Agent' => "Mozilla/5.0",
  30. 'KeepAlive' => 300,
  31. 'Accept' => 'image/png,image/*;q=0.8,*/*;q=0.5',
  32. 'Accept-Language' => 'ru,en-us;q=0.7,en;q=0.3',
  33. 'Accept-Encoding' => 'gzip,deflate',
  34. 'Accept-Charset' => 'windows-1251,utf-8;q=0.7,*;q=0.7',
  35. 'Connection' => 'keep-alive',
  36. 'Authorization' => "Basic $authorization_parameter"
  37. );
  38. my($code, $mess, %h) = $s->read_response_headers;
  39.  
  40. my $boundary = undef;
  41.  
  42. for($h{'Content-type'})
  43. {
  44. die "inappropriate Content-type" unless /multipart\/x-mixed-replace/;
  45. die "cannot find boundary from response header" unless /boundary=/;
  46. $boundary = $';
  47. }
  48.  
  49. my $current_buf;
  50. my $content_length = undef;
  51. my $boundary_found = undef;
  52. my $content_type = undef;
  53. my $new_line = undef;
  54. my $skip_the_socket_read = undef;
  55.  
  56. my ($cur_hour, $cur_mday,$cur_mon,$cur_year);
  57. my $sub_dir_created = undef;
  58.  
  59. MAIN_HTTP_READ:while (1) {
  60. my $buf;
  61. my $n = undef;
  62.  
  63. unless($skip_the_socket_read)
  64. {
  65. $n = $s->read_entity_body($buf, 1024);
  66. die "http data read failed: $!" unless defined $n;
  67. last unless $n;
  68. $current_buf.= $buf;
  69. }
  70. else
  71. {
  72. $skip_the_socket_read = undef;
  73. }
  74.  
  75. unless($boundary_found)
  76. {
  77. for($current_buf)
  78. {
  79. do
  80. {
  81. die "Strange Motion Jpeg. Looks like either parser error or unsupported device" if length($current_buf) >= length($boundary) + 2;
  82. next MAIN_HTTP_READ;
  83. } unless /^$boundary\r\n/m;
  84. $current_buf = $';
  85. $boundary_found = 1;
  86. }
  87. }
  88.  
  89. unless($content_length)
  90. {
  91. for($current_buf)
  92. {
  93. do
  94. {
  95. die "Strange Motion Jpeg. Looks like either parser error or unsupported device" if /\r\n/;
  96. next MAIN_HTTP_READ;
  97. } unless /^Content-length: (\d+)\r\n/;
  98. $current_buf = $';
  99. $content_length = $1;
  100. }
  101. }
  102.  
  103. unless($content_type)
  104. {
  105. for($current_buf)
  106. {
  107. do
  108. {
  109. die "Strange Motion Jpeg. Looks like either parser error or unsupported device" if length($current_buf) >= length("Content-type: image\/jpeg\r\n") + 2;
  110. next MAIN_HTTP_READ;
  111. } unless /^Content-type: image\/jpeg\r\n/;
  112. $current_buf = $';
  113. }
  114. $content_type = 1;
  115. }
  116.  
  117. unless($new_line)
  118. {
  119. for($current_buf)
  120. {
  121. do
  122. {
  123. die "Strange Motion Jpeg. Looks like either parser error or unsupported device" if length($current_buf) >= 2;
  124. next MAIN_HTTP_READ;
  125. } unless /^\r\n/;
  126.  
  127. $current_buf = $';
  128. $new_line = 1;
  129. }
  130. }
  131.  
  132. # lets read the body
  133. my $current_buf_length = length($current_buf);
  134. my $need_2_read = ($content_length + 2) - $current_buf_length;
  135.  
  136. until(0 >= $need_2_read) # we don't already have the whole body
  137. {
  138. $n = $s->read_entity_body($buf, 1024);
  139. die "http data read failed: $!" unless defined $n;
  140. last unless $n;
  141. $current_buf.= $buf;
  142.  
  143. $current_buf_length = length($current_buf);
  144. $need_2_read = ($content_length + 2) - $current_buf_length;
  145. }
  146.  
  147. if(0 > $need_2_read)
  148. {
  149. $skip_the_socket_read = 1;
  150. }
  151.  
  152. $cur_body = substr $current_buf, 0, $content_length, '';
  153.  
  154. ($sec,$min,$hour,$mday,$mon,$year) = localtime;
  155.  
  156. if( !(defined($cur_hour) && defined($cur_mday) && defined($cur_mon) && defined($cur_year)) ||
  157. !( $cur_hour eq $hour && $cur_mday eq $mday && $cur_mon eq $mon && $cur_year eq $year) )
  158. {
  159. $sub_dir_created = undef;
  160. }
  161.  
  162. unless($sub_dir_created)
  163. {
  164. if(defined($cur_hour) and defined($cur_mday) and defined($cur_mon) and defined($cur_year))
  165. {
  166. # goto video archive root
  167. chdir ".." or die "cannot open videoarchive root directory";
  168. }
  169.  
  170. ($cur_hour, $cur_mday, $cur_mon, $cur_year) = ($hour, $mday, $mon, $year);
  171. $dir_name = join '-', $year, $mon + 1, $mday, $hour;
  172.  
  173. unless(-d $dir_name)
  174. {
  175. mkdir $dir_name or die "cannot create $dir_name directory";
  176. }
  177.  
  178. chdir $dir_name or die "cannot change directory to $dir_name";
  179.  
  180. $sub_dir_created = 1;
  181. }
  182.  
  183.  
  184.  
  185. $file_name = join '-', $year, $mon + 1, $mday, $hour, $min, $sec;
  186. $file_name_finally = $file_name . '.jpeg';
  187.  
  188. my $index = 0;
  189. while(-e $file_name_finally)
  190. {
  191. $file_name_finally = $file_name .'-'. $index . '.jpeg';
  192. $index++;
  193. }
  194.  
  195. open JPEG_FILE, ">$file_name_finally" or die "cannot open file $file_name_finally";
  196. binmode JPEG_FILE;
  197. print JPEG_FILE $cur_body or die "cannot print into the file $file_name_finally";
  198. close JPEG_FILE or die "cannot close the file $file_name_finally";
  199.  
  200. for($current_buf)
  201. {
  202. die "Strange Motion Jpeg. Looks like either parser error or unsupported device" unless /\r\n/;
  203. $current_buf = $';
  204. }
  205.  
  206. $content_length = undef;
  207. $boundary_found = undef;
  208. $content_type = undef;
  209. $new_line = undef;
  210. }
  211.  
  212. __END__
Сохраняет в папку 'archive' jpeg картинки полученные с камеры. Возможно будет работать с другими типами ip камер panasonic.
Небольшие изменения позволят работать с камерами axis и d-link
perl motionJpeg.pl -p xolopp -u ppolox -f archive -i 192.168.0.253
Поддержку работы функций ptz пока не добавлял.

(с)rsdn.ru/Forum/message/3270384.aspx

+добавить реализацию