Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PHPとRustを組み合わせて音声ファイルをエンコードする話

Shumpei Urabe
February 11, 2020

 PHPとRustを組み合わせて音声ファイルをエンコードする話

PHPerKaigi 2020
https://phperkaigi.jp/2020/

Shumpei Urabe

February 11, 2020
Tweet

More Decks by Shumpei Urabe

Other Decks in Technology

Transcript

  1. RustͰΤϯίʔυ͢Δ෦෼Λ࣮૷͢Δ #[no_mangle] pub extern "C" fn encode(data: *mut u8, length:

    u32) -> *const c_char { unsafe { let buf: &mut [u8] = core::slice::from_raw_parts_mut(data, length as usize); let mut ptr = io::Cursor::new(buf); let mut wav_reader = hound::WavReader::new(&mut ptr).unwrap(); let mut data = Vec::new(); for sample in wav_reader.samples() { match sample { Ok(smpl) => data.push(smpl), _ => panic!("failed"), } } let timestamp = Rational64::from_integer(0); let raw_frame = RawFrame { timestamp, data }; let mut encoder = Encoder::new(); let output_file_name = encoder.encode(raw_frame); return CString::new(output_file_name) .expect("failed") .into_raw(); } }
  2. μΠφϛοΫϥΠϒϥϦΛಡΈࠐΉ $signature = "const char* encode(uint8_t *data, uint32_t length);"; return

    \FFI::cdef( $signature, __DIR__ . "/../target/ release/libmp3encoder.dylib");
  3. FFIͷݺͼग़͠ͱ࣮ߦ $ffi = loadLibrary(); $length = \strlen($value); $buffer = FFI::new(FFI::arrayType($ffi->type('uint8_t'),

    [$length])); FFI::memcpy($buffer, $value, $length); $bufferPtr = FFI::cast($ffi->type('uint8_t*'), $buffer); $outputFileName = $ffi->encode($bufferPtr, $length);