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

Cb4d62dd7c1d325863696c45e9b6484d?s=47 Shumpei Urabe
February 11, 2020

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

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

Cb4d62dd7c1d325863696c45e9b6484d?s=128

Shumpei Urabe

February 11, 2020
Tweet

Transcript

  1. 7.
  2. 11.
  3. 15.

    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(); } }
  4. 17.

    μΠφϛοΫϥΠϒϥϦΛಡΈࠐΉ $signature = "const char* encode(uint8_t *data, uint32_t length);"; return

    \FFI::cdef( $signature, __DIR__ . "/../target/ release/libmp3encoder.dylib");
  5. 19.

    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);
  6. 22.