In this first example, we’ll use Valeo to control an Erlang VM with some arguments.
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 | %% copy the following into a file called: "vm.erl"
-module(vm).
-export([
start/0, stop/1,
%% behaviour callbacks
valeo_init/1,
valeo_handle_info/2,
valeo_terminate/1
]).
-behavior(valeo).
start() -> %% run an Erlang VM under VALEO supervision
ProgArgs =[
{cmd_name, "erl"},
{cmd_params, ["+Ktrue", "+B", "-noshell", {"-pa", "ebin"}]}
],
PortArgs =[
{port_id, ?MODULE},
{port_pidfile, "vm.pid"}
],
valeo:start_link(?MODULE, ProgArgs, PortArgs).
stop(Port) -> %% stop the Erlang VM
valeo:stop(Port).
%% --- callback functions ---
valeo_init(_) ->
{ok, []}.
valeo_handle_info({exit_status, 0}, State) ->
{stop, normal}; %% normal exit of the VM, do not restart
valeo_handle_info({exit_status, Status}, State) ->
io:format("VM exited with error code: ~p", [Status]),
{stop, need_restart}. %% always restart-it
valeo_terminate(State) ->
ok. %% cleanup
|
c:\> erlc vm.erl
c:\> werl
Erlang R15B01 (erts-5.9.1) [source] [64-bit] [smp:2:2] [async-threads:0] [kernel-poll:false]
Eshell V5.9.1 (abort with ^G)
1> {ok, Port} = vm:start().
2> valeo:proc_id(Port). %% returns the OS process ID
5056
3> valeo:stop(Port).
4> q().
Line 29: the callback function valeo_init/1 is very similar to gen_server one. Use it to keep a state (ex. []) during the Valeo instance execution. Its parameter is the current process id (self()).
Let’s see how to proceed!
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 | %% copy the following into a file called: "vlc.erl"
-module(vlc).
-export([
start/0, stop/1,
%% behaviour callbacks
valeo_init/1,
valeo_handle_info/2,
valeo_terminate/1
]).
-behavior(valeo).
-define(VLC_PARAMS(Dur,Stm,Out,Mux), "--stop-time " ++
Dur ++ " --run-time=" ++ Dur ++ " " ++ Stm ++
"--sout='#std{access=file,mux=" ++ Mux ++ ",dst=" ++
Out ++ "}' vlc://quit").
%%--------------------------------------------------------------------
%% @doc Drive VLC player from command line.
%% @end
%%--------------------------------------------------------------------
start() ->
Stream = "rtsp://media6.lsops.net:1935/live/bbcworld1_en_high.sdp",
Output = "bbc.mp4", %% output file
Duration = 30, %% 30 sec.
Muxer = "ts",
PidFile = filename:basename(Output ++ ".pid"), %% must be unique name
ProgArgs = [
{cmd_name, "vlc"},
{cmd_params,
["-I dummy", %% run without GUI (console mode)
"-q", %% quiet mode
?VLC_PARAMS(integer_to_list(Duration), Stream, Output, Muxer)
]}
],
PortArgs = [
{port_id, ?MODULE},
{port_mode, 'active'},
{port_opts, [stderr_to_stdout]},
{port_stop_after, 3 * 1000}, %% force stop after 3sec.
{port_pidfile, PidFile}
],
io:format("Capture live stream from: ~p~n", [Stream]),
io:format("Stream duration ~psec.~n", [Duration]),
io:format("Save the stream into: ~p~n", [Output]),
%% run VLC player and capture live BBC stream
{ok, Port} = valeo:start_link(?MODULE, ProgArgs, PortArgs),
%% stop VLC after 30sec.
{ok, _} = timer:apply_after(Duration * 1000, ?MODULE, stop, [Port]).
%%--------------------------------------------------------------------
%% @doc Stop VLC player
%% @end
%%--------------------------------------------------------------------
stop(Pid) ->
valeo:stop(Pid).
%%--------------------------------------------------------------------
%% @doc Initiate the valeo server
%% @end
%%--------------------------------------------------------------------
valeo_init(Pid) ->
io:format("VLC started: ~p~n", [Pid]),
{ok, []}.
%%--------------------------------------------------------------------
%% @doc Callback to handle messages coming from the external program.
%% @end
%%--------------------------------------------------------------------
valeo_handle_info({exit_status, _}, _State) ->
{stop, 'normal'};
valeo_handle_info({data, Data}, State) ->
io:format("Got data from VLC: ~p~n", [Data]),
{ok, State}.
%%--------------------------------------------------------------------
%% @doc Terminate the valeo server.
%% @end
%%--------------------------------------------------------------------
valeo_terminate(_State) ->
io:format("VLC closed~n"),
ok.
|
$ erlc vlc.erl
$ erl
Erlang R15B01 (erts-5.9.1) [source] [64-bit] [smp:2:2] [async-threads:0] [kernel-poll:false]
Eshell V5.9.1 (abort with ^G)
1> {ok, _} = vlc:start().
%% wait 30 seconds to let VLC automatically finish the task (no need to manually stop it).
2> q().
Note
Exercise