@@ -21,7 +21,7 @@ use mediainfo_rs::{
2121use std:: {
2222 env,
2323 fs:: File ,
24- io:: { self , Read , Seek , SeekFrom } ,
24+ io:: { self , Read , Seek , SeekFrom , Write } ,
2525} ;
2626
2727fn main ( ) {
@@ -102,6 +102,9 @@ fn main() {
102102
103103 // MediaInfoList example
104104 //mediainfo_list();
105+
106+ // File_Duplicate by buffer example
107+ //file_duplicate_buffer().unwrap();
105108}
106109
107110//***************************************************************************
@@ -260,3 +263,101 @@ fn mediainfo_list() {
260263 mi. count_get_files( )
261264 ) ;
262265}
266+
267+ //***************************************************************************
268+ // File_Duplicate by buffer example
269+ // https://mediaarea.net/en/MediaInfo/Support/SDK/Duplicate
270+ //***************************************************************************
271+ #[ allow( dead_code) ] //suppress warnings when this function is not called by main
272+ fn file_duplicate_buffer ( ) -> io:: Result < ( ) > {
273+ //From: preparing an example file for reading
274+ //For this example, MPTS.ts is a file generated with:
275+ // ffmpeg -f lavfi -i "testsrc=duration=10:size=1280x720:rate=25" \
276+ // -f lavfi -i "sine=frequency=440:duration=10" \
277+ // -f lavfi -i "testsrc=duration=10:size=640x480:rate=30" \
278+ // -f lavfi -i "sine=frequency=880:duration=10" \
279+ // -map 0:v:0 -map 1:a:0 -map 2:v:0 -map 3:a:0 \
280+ // -program title=ProgOne:st=0:st=1 -program title=ProgTwo:st=2:st=3 \
281+ // -c:v libx264 -c:a aac -f mpegts MPTS.ts
282+ let mut f = File :: open ( "MPTS.ts" ) ?;
283+
284+ //From: preparing a memory buffer for reading
285+ let mut from_buffer = [ 0u8 ; 102400 ] ; //Note: you can do your own buffer
286+ let mut from_buffer_size; //The size of the read file buffer
287+
288+ //To: preparing a memory buffer for writing
289+ let to_buffer = [ 0u8 ; 102400 ] ; //Note: you can do your own buffer
290+ let mut to_buffer_size_written; //The size of the output buffer that is written by MediaInfo
291+
292+ //Destination file
293+ let mut of = File :: create ( "MPTS_File_Duplicate.ts" ) ?;
294+
295+ //From: retrieving file size
296+ f. seek ( SeekFrom :: End ( 0 ) ) ?;
297+ let f_size = f. stream_position ( ) ?;
298+ f. seek ( SeekFrom :: Start ( 0 ) ) ?;
299+
300+ //Initializing MediaInfo
301+ let mi = MediaInfo :: new ( ) ;
302+
303+ //Registering for duplication
304+ //The streams has multiple programs, one of these program is named "1".
305+ //The user wants to have this program, and only this one, in the output.
306+ mi. option (
307+ "File_Duplicate" ,
308+ & format ! (
309+ "memory://{}:{};program_number={}" ,
310+ to_buffer. as_ptr( ) as usize ,
311+ to_buffer. len( ) ,
312+ 1
313+ ) ,
314+ ) ;
315+
316+ //Setting MediaInfo as parsing a non seakable file, because we want the complete stream
317+ mi. option ( "File_IsSeekable" , "0" ) ;
318+
319+ //Preparing to fill MediaInfo with a buffer
320+ mi. open_buffer_init ( f_size, 0 ) ;
321+
322+ //The parsing loop
323+ let mut can_write_only_if_parsing_is_ok = false ;
324+ loop {
325+ //Reading data somewhere, do what you want for this.
326+ from_buffer_size = f. read ( & mut from_buffer) ?;
327+
328+ //Sending the buffer to MediaInfo
329+ let status = mi. open_buffer_continue ( & from_buffer, from_buffer_size) ;
330+ if status & 0x1 == 0x1 && !can_write_only_if_parsing_is_ok {
331+ can_write_only_if_parsing_is_ok = true ;
332+ }
333+
334+ if can_write_only_if_parsing_is_ok {
335+ //Retrieving data written in memory
336+ to_buffer_size_written = mi. output_buffer_get ( & format ! (
337+ "memory://{}:{}" ,
338+ to_buffer. as_ptr( ) as usize ,
339+ to_buffer. len( )
340+ ) ) ;
341+
342+ //Writing data to somewhere, do what you want for this.
343+ of. write_all ( & to_buffer[ 0 ..to_buffer_size_written] ) ?;
344+ }
345+
346+ if from_buffer_size == 0 {
347+ break ;
348+ }
349+ }
350+
351+ //Finalizing
352+ mi. open_buffer_finalize ( ) ; //This is the end of the stream, MediaInfo must finnish some work
353+
354+ //Inform
355+ mi. option ( "Inform" , "" ) ; //reset to default due to previous changes in examnple main()
356+ mi. option ( "Complete" , "" ) ; //reset to default due to previous changes in examnple main()
357+ println ! ( "\n Original:\n \n {}" , mi. inform( ) ) ;
358+ let mi2 = MediaInfo :: new ( ) ;
359+ mi2. open ( "MPTS_File_Duplicate.ts" ) ;
360+ println ! ( "\n Duplicated::\n \n {}" , mi2. inform( ) ) ;
361+
362+ Ok ( ( ) )
363+ }
0 commit comments