larksuite / rsmpeg

A Rust crate that exposes FFmpeg's power as much as possible.
https://docs.rs/rsmpeg/latest/rsmpeg/
MIT License
678 stars 41 forks source link

Add avio_writing test #48

Closed imxood closed 3 years ago

imxood commented 3 years ago

use AVFormatContextOutput::create function, create custom io, test

ldm0 commented 3 years ago

阿sir,通过hack手段实现seek,写出来的视频文件当然会有问题(((

ldm0 commented 3 years ago
    let buffer = Arc::new(Mutex::new(File::create(filename.to_str()?)?));
    let buffer1 = buffer.clone();
    // Custom IO Context
    let io_context = AVIOContextCustom::alloc_context(
        AVMem::new(4096),
        true,
        vec![],
        None,
        Some(Box::new(move |_: &mut Vec<u8>, buf: &[u8]| {
            let mut buffer = buffer1.lock().unwrap();
            println!("write package, size: {:?}", buf.len());
            buffer.write_all(buf).unwrap();
            buf.len() as _
        })),
        Some(Box::new(
            move |_: &mut Vec<u8>, offset: i64, whence: i32| {
                let mut buffer = buffer.lock().unwrap();
                let mut seek_ = |offset: i64, whence: i32| -> Result<u64> {
                    Ok(match whence {
                        libc::SEEK_CUR => buffer.seek(SeekFrom::Current(offset))?,
                        libc::SEEK_SET => buffer.seek(SeekFrom::Start(offset as u64))?,
                        libc::SEEK_END => buffer.seek(SeekFrom::End(offset))?,
                        _ => unimplemented!(),
                    })
                };
                seek_(offset, whence).expect("Seek failed") as i64
            },
        )),
    );

@imxood 亲测有效,IOContext那部分修正成这样即可。

imxood commented 3 years ago

确定了, 你的seek, 没有问题~ 是我刚开始没太明白这里seek的含义

ldm0 commented 3 years ago

那我先合并这个PR,然后再改一下