I want to shoot a video with a pressense.

Asked 2 years ago, Updated 2 years ago, 77 views

camera.ino provides an example of capturing JPG.
By the way, is it possible to take a video?
At that time, is it possible to record the sound as well?

spresense arduino

2022-09-30 12:06

2 Answers

Just a little while ago, I made a sketch to take a video with AVI, which is only about 8fps, but if you go into the Arduino Camera library in Spresense, you may be able to get a little more fps.Unfortunately, this sketch does not support sound.

#include<Camera.h>
# include <SDHCI.h>
# include <stdio.h>
# include <math.h>

SDClass theSD;

/* WIDTH== 1280 (0x500)*/
#define WIDTH_10x00
#define WIDTH_20x05
/* HEIGHT==960(0x3C0)*/
#define HEIGHT_10xC0
#define HEIGHT_20x03
#define TOTAL_FRAMES300
#define AVIOFFSET240

unsigned long movie_size = 0;
const char avi_header [AVIOFFSET+1] = {
  0x52, 0x49, 0x46, 0x46, 0xD8, 0x01, 0x0E, 0x00, 0x41, 0x56, 0x49, 0x20, 0x4C, 0x49, 
  0x53, 0x54, 0xD0, 0x00, 0x00, 0x68, 0x64, 0x72, 0x6C, 0x61, 0x76, 0x69, 0x68, 
  0x38, 0x00, 0x00, 0x00, 0xA0, 0x86, 0x01, 0x00, 0x80, 0x66, 0x01, 0x00, 0x00, 
  0x00, 0x00, 0x10, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, WIDTH_1, WIDTH_2, 0x00, 0x00, 
  HEIGHT_1, HEIGHT_2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x49, 0x53, 0x54, 0x84, 0x00, 
  0x00, 0x00, 0x73, 0x74, 0x72, 0x6C, 0x73, 0x74, 0x72, 0x68, 0x30, 0x00, 0x00, 0x00, 0x00, 
  0x76, 0x69, 0x64, 0x73, 0x4D, 0x4A, 0x50, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x74, 0x72, 0x66, 0x28, 0x00, 0x00, 0x00, 0x00, 
  0x28, 0x00, 0x00, 0x00, WIDTH_1, WIDTH_2, 0x00, 0x00, HEIGHT_1, HEIGHT_2, 
  0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x4D, 0x4A, 0x50, 0x47, 0x00, 0x84, 0x03, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x4C, 0x49, 0x53, 0x54, 0x10, 0x00, 0x00, 0x00, 0x6F, 0x64, 0x6D, 0x6C, 
  0x64, 0x6D, 0x6C, 0x68, 0x04, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x49, 
  0x53, 0x54, 0x00, 0x01, 0x0E, 0x00, 0x6D, 0x6F, 0x76, 0x69, 0x00
};

File aviFile;
String filename = "movie.avi";
uint32_t start_ms = 0;

static void inline uint32_write_to_aviFile(uint32_tv){ 
  char value = v%0x100;
  aviFile.write(value); v=v>>8; 
  value = v%0x100;
  aviFile.write(value); v=v>>8;
  value = v%0x100;
  aviFile.write(value); v=v>>8; 
  value = v;
  aviFile.write(value);
}


void setup() {
  Serial.begin (115200);

  the Camera.begin();
  theSD.begin();

  theSD.remove(filename);
  aviFile=theSD.open(filename, FILE_WRITE);
  aviFile.write(avi_header, AVIOFFSET);

  Serial.println("Recording...");

  TheCamera.setStillPictureImageFormat(
     CAM_IMGSIZE_QUADVGA_H,
     CAM_IMGSIZE_QUADVGA_V,
     CAM_IMAGE_PIX_FMT_JPG);

  start_ms=millis();
  digitalWrite (LED 0, HIGH);
}

int loopCounter = 0;
void loop() {

  CamImage img=theCamera.takePicture();
  if(!img.isAvailable()){
    Serial.println("fail to take a picture";
    return;
  }

  aviFile.write("00dc", 4);
  uint32_t chunk_top=aviFile.position();

  uint32_tjpeg_size=img.getImgSize();
  uint32_write_to_aviFile(jpeg_size);

  aviFile.write(img.getImgBuff(),jpeg_size);
  movie_size+=jpeg_size;

  /* Presense's jpg file is assigned to be 16 bits aligned 
   * So, there's no padding operation*/

  if(++loopCounter==TOTAL_FRAMES){
    float duration_sec=(millis()-start_ms)/100.0f;
    float fps_in_float=loopCounter/duration_sec;
    float us_per_frame_in_float=1000000.0f/fps_in_float;
    uint32_tfps=round(fps_in_float);
    uint32_tus_per_frame = round(us_per_frame_in_float);

    /* overwrite riff file size*/
    aviFile.seek (0x04);
    uint32_total_size=movi_size+12*loopCounter+4;
    uint32_write_to_aviFile(total_size);

    /* overwrite hdrl*/
    /* hdrl.avih.us_per_frame*/
    aviFile.seek (0x20);
    uint32_write_to_aviFile(us_per_frame);
    uint32_tmax_bytes_per_sec =movi_size*fps/loopCounter;
    aviFile.seek (0x24);
    uint32_write_to_aviFile(max_bytes_per_sec);

    /* hdrl.avih.tot_frames*/
    aviFile.seek (0x30);
    uint32_write_to_aviFile(loopCounter);
    aviFile.seek (0x84);
    uint32_write_to_aviFile(fps);   

    /* hdrl.strl.list_odml.frames*/
    aviFile.seek(0xe0);
    uint32_write_to_aviFile(loopCounter);
    aviFile.seek (0xe8);
    uint32_write_to_aviFile(movi_size);

    aviFile.close();

    Serial.println("Movie saved");
    Serial.println("File size(kB):"+String(total_size)));
    Serial.println("Captured Frame:" + String(loopCounter))); 
    Serial.println("Duration(sec):"+String(duration_sec)));
    Serial.println("Frame persec:"+String(fps)));
    Serial.println("Max data rate:"+String(max_bytes_per_sec)));

    digitalWrite (LED 0, LOW);
    while(1);

  }
}

You can find out how the video was taken on the next blog.For your information.

SPRESENSE has tried supporting AVI videos!
https://makers-with-myson.blog.ss-blog.jp/2019-09-30


2022-09-30 12:06

It's working!
If you set the SD card to Class 10, you could shoot at 10 Fps!

10:44:03.738->Recording...
10:44:32.998 ->Movie saved
10:44:32.998->File size (kB):32472884
10:44:32.998->Captured Frame:300
10:44:32.998->Duration(sec): 29.24
10:44:33.032->Frame persec:10
10:44:33.032->Max data rate:1082309


2022-09-30 12:06

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.