1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
|
let () =
if Array.length Sys.argv < 3 then (
Printf.eprintf "Usage: %s <input_file> <output_file>.mp4\n" Sys.argv.(0);
exit 1);
if Array.length Sys.argv = 4 && Sys.argv.(3) = "macosx" then exit 0;
Avutil.Log.set_level `Verbose;
let src = Av.open_input Sys.argv.(1) in
let idx, istream, params = Av.find_best_audio_stream src in
let () =
match Avcodec.descriptor params with
| Some { name = d; _ } ->
Printf.printf
"Input format: %s (channel layout: %s, sample format: %s, sample \
rate: %d)\n\
%!"
d
(Avutil.Channel_layout.get_description
(Avcodec.Audio.get_channel_layout params))
(Option.value ~default:"(unknown)"
(Avutil.Sample_format.get_name
(Avcodec.Audio.get_sample_format params)))
(Avcodec.Audio.get_sample_rate params)
| _ -> Printf.printf "Unknown input format..\n!"
in
let codec = Avcodec.Audio.find_encoder_by_name "aac" in
let channel_layout = Avcodec.Audio.get_channel_layout params in
let sample_format = Avcodec.Audio.get_sample_format params in
let sample_rate = Avcodec.Audio.get_sample_rate params in
let time_base = { Avutil.num = 1; den = sample_rate } in
let ostream =
Av.open_output Sys.argv.(2)
|> Av.new_audio_stream ~channel_layout ~sample_format ~sample_rate
~time_base ~codec
in
let () =
match Avcodec.descriptor (Av.get_codec_params ostream) with
| Some { name = d; _ } ->
Printf.printf
"Output format: %s (channel layout: %s, sample format: %s, sample \
rate: %d)\n\
%!"
d
(Avutil.Channel_layout.get_description
(Avcodec.Audio.get_channel_layout params))
(Option.value ~default:"(unknown)"
(Avutil.Sample_format.get_name
(Avcodec.Audio.get_sample_format params)))
(Avcodec.Audio.get_sample_rate params)
| _ -> Printf.printf "Unknown output format..\n!"
in
let filter = ref None in
let get_filter frame =
match !filter with
| Some f -> f
| None ->
let in_params =
{
Avfilter.Utils.sample_rate =
Avutil.Audio.frame_get_sample_rate frame;
channel_layout = Avutil.Audio.frame_get_channel_layout frame;
sample_format = Avutil.Audio.frame_get_sample_format frame;
}
in
let in_time_base = { Avutil.num = 1; den = sample_rate } in
let out_frame_size =
if List.mem `Variable_frame_size (Avcodec.capabilities codec) then
512
else Av.get_frame_size ostream
in
let out_params =
{ Avfilter.Utils.sample_rate; sample_format; channel_layout }
in
let f =
Avfilter.Utils.init_audio_converter ~in_params ~in_time_base
~out_params ~out_frame_size ()
in
filter := Some f;
f
in
let pts = ref 0L in
let on_frame frame =
Avutil.Frame.set_pts frame (Some !pts);
pts := Int64.add !pts (Int64.of_int (Avutil.Audio.frame_nb_samples frame));
Av.write_frame ostream frame
in
let write_frame frame =
let filter = get_filter frame in
Avfilter.Utils.convert_audio filter on_frame (`Frame frame)
in
let rec f () =
match Av.read_input ~audio_frame:[istream] src with
| `Audio_frame (i, frame) when i = idx ->
write_frame frame;
f ()
| exception Avutil.Error `Eof -> ()
| _ -> f ()
in
f ();
Av.get_input istream |> Av.close;
Av.get_output ostream |> Av.close;
Gc.full_major ();
Gc.full_major ()
|