Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initiated refactoring of media_provider

  • Loading branch information...
commit abc722fdd63922045ae19f8b913be9072dd69f60 1 parent 66c8d49
Max Lapshin maxlapshin authored
2  doc/media.edoc
View
@@ -38,7 +38,7 @@ Media_stream may be a client of recorded stream from web camera or client of dec
-Media opening:
+Media playing:
1. media_provider makes lookup in table.
24 src/apps/apps_streaming.erl
View
@@ -43,11 +43,11 @@
'WAIT_FOR_DATA'({play, Name, StreamId}, #rtmp_client{client_buffer = ClientBuffer} = State) ->
case media_provider:play(Name, [{stream_id, StreamId}, {client_buffer, ClientBuffer}]) of
- {ok, PlayerPid} ->
- ?D({"Player starting", PlayerPid}),
- PlayerPid ! {start},
- {next_state, 'WAIT_FOR_DATA', State#rtmp_client{video_player = PlayerPid}, ?TIMEOUT};
- {notfound} ->
+ {ok, Player} ->
+ ?D({"Player starting", Player}),
+ Player ! start,
+ {next_state, 'WAIT_FOR_DATA', State#rtmp_client{video_player = Player}, ?TIMEOUT};
+ {notfound, _Reason} ->
gen_fsm:send_event(self(), {status, ?NS_PLAY_STREAM_NOT_FOUND, 1}),
{next_state, 'WAIT_FOR_DATA', State, ?TIMEOUT};
Reason ->
@@ -55,9 +55,9 @@
{error, Reason}
end;
-'WAIT_FOR_DATA'({stop}, #rtmp_client{video_player = PlayerPid} = State) when is_pid(PlayerPid) ->
- ?D({"Stopping video player", PlayerPid}),
- PlayerPid ! {stop},
+'WAIT_FOR_DATA'({stop}, #rtmp_client{video_player = Player} = State) when is_pid(Player) ->
+ ?D({"Stopping video player", Player}),
+ Player ! stop,
{next_state, 'WAIT_FOR_DATA', State, ?TIMEOUT};
@@ -113,7 +113,7 @@ deleteStream(_AMF, #rtmp_client{video_player = undefined} = State) ->
State;
deleteStream(_AMF, #rtmp_client{video_player = Player} = State) when is_pid(Player) ->
- gen_fsm:send_event(Player, {stop}),
+ Player ! stop,
?D("invoke - deleteStream"),
State.
@@ -133,7 +133,7 @@ play(AMF, #rtmp_client{video_player = Player} = State) ->
?D({"invoke - play", Name, AMF}),
case Player of
undefined -> ok;
- _ -> Player ! {stop}
+ _ -> Player ! stop
end,
gen_fsm:send_event(self(), {control, ?RTMP_CONTROL_STREAM_RECORDED, StreamId}),
gen_fsm:send_event(self(), {control, ?RTMP_CONTROL_STREAM_BEGIN, StreamId}),
@@ -154,11 +154,11 @@ pause(AMF, #rtmp_client{video_player = Player} = State) ->
case Pausing of
true ->
- Player ! {pause},
+ Player ! pause,
gen_fsm:send_event(self(), {status, ?NS_PAUSE_NOTIFY, 1}),
State;
false ->
- Player ! {resume},
+ Player ! resume,
gen_fsm:send_event(self(), {status, ?NS_UNPAUSE_NOTIFY, 1}),
State
end.
2  src/ems_rtmp.erl
View
@@ -208,7 +208,7 @@ command(#channel{type = ?RTMP_TYPE_CONTROL, msg = <<?RTMP_CONTROL_STREAM_BUFFER:
?D({"Buffer size on stream id", BufferSize, _StreamId}),
case Player of
undefined -> ok;
- _ -> gen_fsm:send_event(Player, {client_buffer, BufferSize})
+ _ -> Player ! {client_buffer, BufferSize}
end,
State#rtmp_client{client_buffer = BufferSize};
36 src/ems_sup.erl
View
@@ -70,7 +70,9 @@ start_rtsp_client() -> supervisor:start_child(rtsp_client_sup, []).
%% To be called by the media provider.
%% @end
%%--------------------------------------------------------------------
-start_media(Name, Type) -> supervisor:start_child(media_entry_sup, [Name, Type]).
+start_media(Name, file = Type) -> supervisor:start_child(file_media_sup, [Name, Type]);
+start_media(Name, mpeg_ts = Type) -> supervisor:start_child(stream_media_sup, [Name, Type]);
+start_media(Name, live = Type) -> supervisor:start_child(stream_media_sup, [Name, Type]).
%%--------------------------------------------------------------------
%% @spec () -> any()
@@ -119,17 +121,32 @@ init([rtsp_client]) ->
]
}
};
-init([media_entry]) ->
+init([file_media]) ->
{ok,
{_SupFlags = {simple_one_for_one, ?MAX_RESTART, ?MAX_TIME},
[
% MediaEntry
{ undefined, % Id = internal id
- {media_entry,start_link,[]}, % StartFun = {M, F, A}
+ {file_media,start_link,[]}, % StartFun = {M, F, A}
temporary, % Restart = permanent | transient | temporary
2000, % Shutdown = brutal_kill | int() >= 0 | infinity
worker, % Type = worker | supervisor
- [media_entry] % Modules = [Module] | dynamic
+ [file_media] % Modules = [Module] | dynamic
+ }
+ ]
+ }
+ };
+init([stream_media]) ->
+ {ok,
+ {_SupFlags = {simple_one_for_one, ?MAX_RESTART, ?MAX_TIME},
+ [
+ % MediaEntry
+ { undefined, % Id = internal id
+ {stream_media,start_link,[]}, % StartFun = {M, F, A}
+ temporary, % Restart = permanent | transient | temporary
+ 2000, % Shutdown = brutal_kill | int() >= 0 | infinity
+ worker, % Type = worker | supervisor
+ [stream_media] % Modules = [Module] | dynamic
}
]
}
@@ -184,8 +201,15 @@ init([]) ->
[media_provider] % Modules = [Module] | dynamic
},
% Media entry supervisor
- { media_entry_sup,
- {supervisor,start_link,[{local, media_entry_sup}, ?MODULE, [media_entry]]},
+ { file_media_sup,
+ {supervisor,start_link,[{local, file_media_sup}, ?MODULE, [file_media]]},
+ permanent, % Restart = permanent | transient | temporary
+ infinity, % Shutdown = brutal_kill | int() >= 0 | infinity
+ supervisor, % Type = worker | supervisor
+ [] % Modules = [Module] | dynamic
+ },
+ { stream_media_sup,
+ {supervisor,start_link,[{local, stream_media_sup}, ?MODULE, [stream_media]]},
permanent, % Restart = permanent | transient | temporary
infinity, % Shutdown = brutal_kill | int() >= 0 | infinity
supervisor, % Type = worker | supervisor
150 src/media/media_entry.erl → src/media/file_media.erl
View
@@ -1,6 +1,6 @@
% Media entry is instance of some resource
--module(media_entry).
+-module(file_media).
-author(max@maxidoors.ru).
-include("../include/ems.hrl").
-include("../include/media_info.hrl").
@@ -9,25 +9,21 @@
-behaviour(gen_server).
%% External API
--export([start_link/2, subscribe/2, first/1, read/2, file_name/1, seek/2, metadata/1, publish/2, is_stream/1, set_owner/2]).
+-export([start_link/2, first/1, read/2, file_name/1, seek/2, metadata/1]).
%% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
- code_change/3]).
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
start_link(Path, Type) ->
gen_server:start_link(?MODULE, [Path, Type], []).
-subscribe(Server, Client) ->
- gen_server:call(Server, {subscribe, Client}).
-
+first(Server) ->
+ gen_server:call(Server, {first}).
+
read(Server, Player) ->
gen_server:call(Server, {read, Player}).
-first(Server) ->
- gen_server:call(Server, {first}).
-
file_name(Server) ->
gen_server:call(Server, {file_name}).
@@ -37,66 +33,15 @@ seek(Server, Timestamp) ->
metadata(Server) ->
gen_server:call(Server, {metadata}).
-publish(Server, Frame) ->
- gen_server:call(Server, {publish, Frame}).
-
-is_stream(Server) ->
- gen_server:call(Server, {is_stream}).
-
-set_owner(Server, Owner) ->
- gen_server:call(Server, {set_owner, Owner}).
-
init([Name, file]) ->
process_flag(trap_exit, true),
- FileName = filename:join([file_play:file_dir(), Name]),
- case filelib:is_regular(FileName) of
- true ->
- error_logger:info_msg("Opening file ~p~n", [FileName]),
- Clients = ets:new(clients, [set, private]),
- {ok, Info} = open_file(FileName),
- {ok, Info#media_info{clients = Clients, type = file}};
- _ ->
- ignore
- end;
-
-
-init([URL, mpeg_ts]) ->
- process_flag(trap_exit, true),
- error_logger:info_msg("HTTP MPEG TS ~p~n", [URL]),
- Clients = ets:new(clients, [set, private]),
- % Header = flv:header(#flv_header{version = 1, audio = 1, video = 1}),
- Device = ems_sup:start_ts_lander(URL, self()),
- Recorder = #media_info{type=mpeg_ts, file_name = URL, ts_prev = 0, clients = Clients, device = Device},
- {ok, Recorder, ?TIMEOUT};
-
-
-init([Name, live]) ->
- process_flag(trap_exit, true),
- error_logger:info_msg("Live streaming stream ~p~n", [Name]),
+ error_logger:info_msg("Opening file ~p~n", [Name]),
Clients = ets:new(clients, [set, private]),
- % Header = flv:header(#flv_header{version = 1, audio = 1, video = 1}),
- Recorder = #media_info{type=live, ts_prev = 0, clients = Clients},
- {ok, Recorder, ?TIMEOUT};
+ {ok, Info} = open_file(Name),
+ {ok, Info#media_info{clients = Clients, type = file}}.
-init([Name, record]) ->
- process_flag(trap_exit, true),
- error_logger:info_msg("Recording stream ~p~n", [Name]),
- Clients = ets:new(clients, [set, private]),
- FileName = filename:join([file_play:file_dir(), Name ++ ".flv"]),
- (catch file:delete(FileName)),
- Header = flv:header(#flv_header{version = 1, audio = 1, video = 1}),
- ?D({"Recording to file", FileName}),
- case file:open(FileName, [write, {delayed_write, 1024, 50}]) of
- {ok, Device} ->
- file:write(Device, Header),
- Recorder = #media_info{type=record, device = Device, file_name = FileName, ts_prev = 0, clients = Clients},
- {ok, Recorder, ?TIMEOUT};
- _Error ->
- ignore
- end.
-
%%-------------------------------------------------------------------------
@@ -112,12 +57,12 @@ init([Name, record]) ->
%% @private
%%-------------------------------------------------------------------------
-handle_call({subscribe, Client}, _From, #media_info{file_name = Name, clients = Clients} = MediaInfo) when is_pid(Client) ->
- ets:insert(Clients, {Client}),
- link(Client),
- ?D({"Link from to", Name, self(), Client, ets:info(Clients, size)}),
- % link(_From),
- {reply, ok, MediaInfo};
+handle_call({create_player, Options}, _From, #media_info{file_name = Name, clients = Clients} = MediaInfo) ->
+ {ok, Pid} = file_play:start(self(), Options),
+ ets:insert(Clients, {Pid}),
+ link(Pid),
+ ?D({"Creating media player for", Name, "client", proplists:get_value(consumer, Options)}),
+ {reply, {ok, Pid}, MediaInfo};
handle_call({first}, _From, #media_info{frames = FrameTable} = MediaInfo) ->
@@ -145,37 +90,6 @@ handle_call({metadata}, _From, MediaInfo) ->
{reply, undefined, MediaInfo};
-handle_call({is_stream}, _From, #media_info{type = record} = MediaInfo) ->
- {reply, true, MediaInfo};
-
-handle_call({is_stream}, _From, MediaInfo) ->
- {reply, false, MediaInfo};
-
-
-handle_call({set_owner, Owner}, _From, #media_info{owner = undefined} = MediaInfo) ->
- ?D({"Setting owner to", Owner}),
- {reply, ok, MediaInfo#media_info{owner = Owner}};
-
-handle_call({set_owner, _Owner}, _From, #media_info{owner = Owner} = MediaInfo) ->
- {reply, {error, {owner_exists, Owner}}, MediaInfo};
-
-
-handle_call({publish, Channel}, _From, #media_info{ts_prev = PrevTs, device = Device, clients = Clients} = Recorder) ->
- % ?D({"Record",Channel#channel.id, Channel#channel.type,size(Channel#channel.msg),Channel#channel.timestamp,PrevTs}),
- {Tag,NextTimeStamp} = ems_flv:to_tag(Channel,PrevTs),
- case Device of
- undefined -> ok;
- _ -> file:write(Device, Tag)
- end,
-
- NextTimeStamp = PrevTs + Channel#channel.timestamp,
- % ?D({"Broadcast",Channel#channel.id,Channel#channel.type,size(Channel#channel.msg),NextTimeStamp}),
- Packet = Channel#channel{id = ems_play:channel_id(Channel#channel.type,1), timestamp = NextTimeStamp},
- % ?D({"Broadcast to", ets:info(Clients, size)}),
- ets:foldl(fun send_packet/2, Packet, Clients),
-
- {reply, ok, Recorder#media_info{ts_prev = NextTimeStamp}};
-
handle_call(Request, _From, State) ->
?D({"Undefined call", Request, _From}),
{stop, {unknown_call, Request}, State}.
@@ -231,30 +145,6 @@ handle_info({'EXIT', Client, _Reason}, #media_info{clients = Clients} = MediaInf
end,
{noreply, MediaInfo};
-handle_info({'$gen_event', {stop}}, State) ->
- {noreply, State};
-
-handle_info({'$gen_event', {exit}}, State) ->
- {noreply, State};
-
-handle_info({'$gen_event', {start}}, State) ->
- {noreply, State};
-
-handle_info({'$gen_event', {video, Video}}, #media_info{type = mpeg_ts, clients = Clients} = MediaInfo) ->
- % Packet = Channel#channel{id = ems_play:channel_id(video,1), timestamp = NextTimeStamp},
- % ets:foldl(fun send_packet/2, Packet, Clients),
-
- {noreply, MediaInfo};
-
-handle_info({'$gen_event', {send, Packet}}, #media_info{type = mpeg_ts, clients = Clients} = MediaInfo) ->
- % ?D(Frame),
- % Packet = Channel#channel{id = ems_play:channel_id(video,1), timestamp = NextTimeStamp},
- ets:foldl(fun send_packet/2, Packet, Clients),
-
- {noreply, MediaInfo};
-
-
-
handle_info(_Info, State) ->
?D({"Undefined info", _Info}),
@@ -282,16 +172,6 @@ terminate(_Reason, #media_info{device = Device} = _MediaInfo) ->
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
-send_packet({Client}, #channel{msg = Data} = Channel) ->
- % ?D({"Send to", Client}),
- gen_fsm:send_event(Client, {send, {Channel, Data}}),
- Channel;
-
-send_packet({Client}, Packet) ->
- % ?D({"Send to", Client}),
- gen_fsm:send_event(Client, {send, Packet}),
- Packet.
-
open_file(Name) ->
FileName = filename:join([file_play:file_dir(), Name]),
{ok, Device} = file:open(FileName, [read, binary, {read_ahead, 100000}]),
29 src/media/file_play.erl
View
@@ -51,12 +51,13 @@ start(MediaEntry, Options) ->
init(MediaEntry, Options) ->
+ ?D({"Starting file play for consumer", proplists:get_value(consumer, Options)}),
ready(#video_player{consumer = proplists:get_value(consumer, Options),
- stream_id = proplists:get_value(stream_id, Options, 1),
- pos = undefined,
- media_info = MediaEntry,
- client_buffer = proplists:get_value(client_buffer, Options, 10000),
- timer_start = erlang:now()}).
+ stream_id = proplists:get_value(stream_id, Options, 1),
+ pos = undefined,
+ media_info = MediaEntry,
+ client_buffer = proplists:get_value(client_buffer, Options, 10000),
+ timer_start = erlang:now()}).
ready(#video_player{media_info = MediaInfo,
@@ -66,24 +67,24 @@ ready(#video_player{media_info = MediaInfo,
stream_id = StreamId} = State) ->
receive
{client_buffer, ClientBuffer} -> ready(State#video_player{client_buffer = ClientBuffer});
- {start} ->
+ start ->
case media_entry:metadata(MediaInfo) of
undefined -> ok;
MetaData -> gen_fsm:send_event(Consumer, {metadata, ?AMF_COMMAND_ONMETADATA, MetaData, 1})
end,
- self() ! {play},
+ self() ! play,
NextState = State#video_player{prepush = ClientBuffer},
?D({"Player starting with pid", self(), MediaInfo}),
?MODULE:ready(NextState);
- {pause} ->
+ pause ->
?D("Player paused"),
timer:cancel(Timer),
?MODULE:ready(State);
- {resume} ->
+ resume ->
?D("Player resumed"),
- self() ! {play},
+ self() ! play,
?MODULE:ready(State);
{seek, Timestamp} ->
@@ -93,15 +94,15 @@ ready(#video_player{media_info = MediaInfo,
self() ! {play},
?MODULE:ready(State#video_player{pos = Pos, ts_prev = NewTimestamp, playing_from = NewTimestamp, prepush = ClientBuffer});
- {stop} ->
+ stop ->
?D("Player stopping"),
timer:cancel(Timer),
?MODULE:ready(State#video_player{ts_prev = 0, pos = media_entry:first(MediaInfo), playing_from = 0});
- {exit} ->
+ exit ->
ok;
- {play} ->
+ play ->
% {_, Sec1, MSec1} = erlang:now(),
case media_entry:read(MediaInfo, State) of
{ok, done} ->
@@ -114,7 +115,7 @@ ready(#video_player{media_info = MediaInfo,
{Timeout, Player1} = timeout(Frame, Player),
% ?D({"Frame", Frame#video_frame.timestamp_abs, Player#video_player.timer_start, TimeStamp, Timeout}),
NextState = Player1#video_player{
- timer_ref = timer:send_after(Timeout, {play}),
+ timer_ref = timer:send_after(Timeout, play),
ts_prev = Frame#video_frame.timestamp_abs,
pos = Frame#video_frame.nextpos},
% {_, Sec2, MSec2} = erlang:now(),
165 src/media/media_provider.erl
View
@@ -8,11 +8,10 @@
-behaviour(gen_server).
%% External API
--export([start_link/0, open/2, create/2, play/1, play/2]).
+-export([start_link/0, create/2, play/1, play/2]).
%% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
- code_change/3]).
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
-record(media_provider, {
opened_media
@@ -28,13 +27,15 @@ start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
-% Opens media of type Type, named Name
-open(Name, Type) ->
- gen_server:call(?MODULE, {open, Name, Type}).
-
create(Name, Type) ->
?D({"Create", Name, Type}),
- gen_server:call(?MODULE, {open, Name, Type}).
+ gen_server:call(?MODULE, {create, Name}).
+
+open(Name) ->
+ gen_server:call(?MODULE, {open, Name}).
+
+find(Name) ->
+ gen_server:call(?MODULE, {find, Name}).
% Plays media with default options
@@ -45,68 +46,26 @@ play(Name) -> play(Name, []).
% consumer: pid of media consumer
% stream_id: for RTMP, FLV stream id
% client_buffer: client buffer size
-play(Name, OriginalOptions) ->
- case find(Name) of
- undefined -> open_file(Name, Options);
- Server -> connect_to_media(Server, Options)
+play(Name, Options) ->
+ case find_or_open(Name) of
+ {notfound, Reason} -> {notfound, Reason};
+ MediaEntry -> create_player(MediaEntry, Options)
end.
-connect_to_media(Server, Options) ->
- Consumer = proplists:get_value(consumer, OriginalOptions, self()),
- case media_entry:is_stream(Server) of
- true ->
- media_entry:subscribe(Server, Consumer),
- {ok, Server};
- _ ->
- file_play:start(Server, Options)
- end.
-
-% init_file(Name, StreamId, State) ->
-% case start_file_play(Name, State, StreamId) of
-% {ok, Pid} -> {ok, Pid};
-% _ -> init_mpeg_ts(Name, StreamId, State)
-% end.
-%
-% init_mpeg_ts(FileName, StreamId, State) ->
-% {ok, Re} = re:compile("http://(.*).ts"),
-% case re:run(FileName, Re) of
-% {match, _Captured} -> mpeg_ts:play(FileName, StreamId, State);
-% _ -> init_stream(FileName, StreamId, State)
-% end.
-%
-% init_stream(Name, _StreamId, _State) ->
-% case ems:get_var(netstream, undefined) of
-% undefined -> {notfound};
-% NetStreamNode -> case rpc:call(NetStreamNode, rtmp, start, [Name], ?TIMEOUT) of
-% {ok, NetStream} ->
-% link(NetStream),
-% ?D({"Netstream created", NetStream}),
-% {ok, NetStream};
-% _ ->
-% {notfound}
-% end
-% end.
-
-open_file("http://"++_ = URL, Options) ->
- case open(URL, mpeg_ts) of
- undefined -> {notfound};
- Server ->
- ?D("Started MPEG TS lander"),
- media_entry:subscribe(Server, proplists:get_value(consumer, Options)),
- {ok, Server}
- end;
-
-
-open_file(Name, Options) ->
- case open(Name, file) of
- undefined -> {notfound};
- Server -> file_play:start(Server, Options)
+find_or_open(Name) ->
+ case find(Name) of
+ undefined -> open(Name);
+ MediaEntry -> MediaEntry
end.
-
-find(Name) ->
- gen_server:call(?MODULE, {find, Name}).
+create_player({notfound, Reason}, _) ->
+ {notfound, Reason};
+
+create_player(MediaEntry, Options) ->
+ gen_server:call(MediaEntry, {create_player, lists:keymerge(1, Options, [{consumer, self()}])}).
+
+
init([]) ->
process_flag(trap_exit, true),
@@ -130,51 +89,57 @@ init([]) ->
%%-------------------------------------------------------------------------
-handle_call({find, Name}, _From, #media_provider{opened_media = OpenedMedia} = MediaProvider) ->
- Server = case ets:lookup(OpenedMedia, Name) of
- [#media_entry{handler = Pid}] -> Pid;
- [] -> undefined
- end,
- {reply, Server, MediaProvider};
+handle_call({find, Name}, _From, MediaProvider) ->
+ {reply, find_in_cache(Name, MediaProvider), MediaProvider};
+handle_call({open, Name}, {_Opener, _Ref}, MediaProvider) ->
+ {reply, open_media_entry(Name, MediaProvider), MediaProvider};
+
+handle_call(Request, _From, State) ->
+ {stop, {unknown_call, Request}, State}.
-handle_call({open, Name, Type}, {Opener, _Ref}, #media_provider{opened_media = OpenedMedia} = MediaProvider) ->
- ?D({"Lookup for media", Name, ets:lookup(OpenedMedia, Name)}),
- Server = case ets:lookup(OpenedMedia, Name) of
+
+find_in_cache(Name, #media_provider{opened_media = OpenedMedia}) ->
+ case ets:lookup(OpenedMedia, Name) of
[#media_entry{handler = Pid}] -> Pid;
- [] ->
+ _ -> undefined
+ end.
+
+open_media_entry(Name, #media_provider{opened_media = OpenedMedia} = MediaProvider) ->
+ case find_in_cache(Name, MediaProvider) of
+ undefined ->
+ Type = detect_type(Name),
case ems_sup:start_media(Name, Type) of
{ok, Pid} ->
link(Pid),
ets:insert(OpenedMedia, #media_entry{name = Name, handler = Pid}),
- ?D({"Inserting", Name, Pid}),
+ ?D({"Opened", Type, Name, Pid}),
Pid;
ignore ->
- undefined
- end
- end,
- case {Server, Type} of
- {undefined, _} ->
- {reply, undefined, MediaProvider};
- {_, file} ->
- ok = media_entry:subscribe(Server, Opener),
- {reply, Server, MediaProvider};
- {_, mpeg_ts} ->
- % ok = media_entry:subscribe(Server, Opener),
- {reply, Server, MediaProvider};
- {_, live} ->
- media_entry:set_owner(Server, Opener),
- {reply, Server, MediaProvider};
- {_, append} ->
- media_entry:set_owner(Server, Opener),
- {reply, Server, MediaProvider};
- {_, record} ->
- media_entry:set_owner(Server, Opener),
- {reply, Server, MediaProvider}
- end;
+ ?D({"Error opening", Type, Name}),
+ {notfound, "Failed to open "++Name}
+ end;
+ MediaEntry ->
+ MediaEntry
+ end.
-handle_call(Request, _From, State) ->
- {stop, {unknown_call, Request}, State}.
+detect_type(Name) ->
+ detect_mpeg_ts(Name).
+
+detect_mpeg_ts(Name) ->
+ {ok, Re} = re:compile("http://(.*).ts"),
+ case re:run(Name, Re) of
+ {match, _Captured} -> mpeg_ts;
+ _ -> detect_file(Name)
+ end.
+
+detect_file(Name) ->
+ FileName = filename:join([file_play:file_dir(), Name]),
+ case filelib:is_regular(FileName) of
+ true -> file;
+ _ -> live
+ end.
+
%%-------------------------------------------------------------------------
%% @spec (Msg, State) ->{noreply, State} |
Please sign in to comment.
Something went wrong with that request. Please try again.