shssoichiro / ffmpeg-the-third

A fork of the abandoned ffmpeg-next crate which is a fork of the abandoned ffmpeg crate
Do What The F*ck You Want To Public License
53 stars 12 forks source link

expose load from io #53

Open Mon-ius opened 2 months ago

Mon-ius commented 2 months ago

current video is from path, which implemented called format::input, for example,


    pub fn clip(&self) -> Result<(), Box<dyn std::error::Error>> {
        ffmpeg_next::init()?;
        let _ = self.mkdir();
        let mut ictx = format::input(&self.path)?;
        let input = ictx
                .streams()
                .best(media::Type::Video)
                .ok_or(ffmpeg_next::Error::StreamNotFound)?;

        let idx = input.index();

        let ctx = codec::context::Context::from_parameters(input.parameters())?;
        let mut decoder = ctx.decoder().video()?;

        let fmt = decoder.format();
        let w = decoder.width();
        let h = decoder.height();

        let mut scaler = software::scaling::context::Context::get(
                fmt, 
                w, h,
                format::Pixel::RGB24,
                w, h,
                software::scaling::flag::Flags::BILINEAR,
            )?;

        let mut i=0;
        let mut count=0;
        for (stream, packet) in ictx.packets() {
            if stream.index() == idx {
                decoder.send_packet(&packet)?;
                let mut decoded_frame = frame::video::Video::empty();
                while decoder.receive_frame(&mut decoded_frame).is_ok() {
                    if count % 5 == 0{
                        let mut rgb_frame = frame::video::Video::empty();
                        scaler.run(&decoded_frame, &mut rgb_frame)?;
                        let img = RgbImage::from_raw(w, h, rgb_frame.data(0).to_vec()).unwrap(); 
                        img.save(self.local.join(format!("{:04}.jpg", i)))?; 
                        i+=1;
                    }
                    count+=1;
                }
            }
        }

        decoder.send_eof()?;
        Ok(())
    }

if that is possible to expose the API, for example,

let mut ictx = format::from_bytes(&self.buffer)?;

FreezyLemon commented 1 month ago

This sounds like a good idea. It will need a fair bit more code than the current format::input function (which should probably be called format::input_from_path) because reading from memory will require a custom AVFormatContext and AVIOContext AFAIK.