1
0
mirror of https://github.com/algora-io/tv.git synced 2025-02-14 01:59:50 +02:00

make new clip video work with multiple manifests

fix download video
This commit is contained in:
ty 2024-10-28 23:19:52 -04:00
parent a8446ddf6d
commit 50248ee74b
2 changed files with 50 additions and 39 deletions

View File

@ -4,6 +4,8 @@ alias Algora.{Accounts, Library, Storage, Repo}
alias Algora.Library.Video
defmodule Algora.Admin do
@audio_track "g3cFYXVkaW8.m3u8"
@video_track "g3cFdmlkZW8.m3u8"
def kill_ad_overlay_processes do
find_ad_overlay_processes() |> Enum.each(&Process.exit(&1, :kill))
@ -218,24 +220,13 @@ defmodule Algora.Admin do
with {:ok, master_resp} <- get(video.url),
{:ok, master_playlist} <- ExM3U8.deserialize_multivariant_playlist(master_resp.body, []) do
Enum.reduce(master_playlist.items, %{}, fn(tag, acc) ->
case tag.uri do
"video_master.m3u8" -> # separate_av video track
acc = Map.put(acc, :video, get_media_playlist(video, tag))
# HACK ExM3U8.Tags.Stream doesn't expose EXT-X-MEDIA:TYPE=AUDIO URI
Map.put(acc, :audio, get_media_playlist(video, %ExM3U8.Tags.Stream{
uri: "audio_master.m3u8",
codecs: "",
bandwidth: 0,
}))
"g3cFdmlkZW8.m3u8" -> # old video track name
Map.put(acc, :video, get_media_playlist(video, tag))
"g3cFYXVkaW8.m3u8" -> # old audio track name
Map.put(acc, :audio, get_media_playlist(video, tag))
_ ->
acc
end
acc = Map.put(acc, tag.uri, get_media_playlist(video, tag))
# HACK ExM3U8.Tags.Stream doesn't expose EXT-X-MEDIA:TYPE=AUDIO URI
Map.put(acc, "audio_master.m3u8", get_media_playlist(video, %ExM3U8.Tags.Stream{
uri: "audio_master.m3u8",
codecs: "",
bandwidth: 0,
}))
end)
end
end
@ -273,16 +264,20 @@ defmodule Algora.Admin do
|> send(:multicast_algora)
end
def download_chunks(chunks, dir) do
def download_chunks(chunks, dir, url_root) do
Task.async_stream(
Enum.with_index(chunks),
fn {chunk, i} ->
IO.puts("#{rounded(100 * i / length(chunks))}%")
name = URI.parse(chunk).path |> String.split("/") |> List.last()
chunk_uri = case URI.parse(chunk) do
%URI{host: nil} -> URI.parse("#{url_root}/#{chunk}")
%URI{} = uri -> uri
end
name = chunk_uri.path |> String.split("/") |> List.last()
dl_path = "#{dir}/#{i}-#{name}"
if not File.exists?(dl_path) do
{:ok, :saved_to_file} =
:httpc.request(:get, {chunk, []}, [],
:httpc.request(:get, {URI.to_string(chunk_uri), []}, [],
stream: ~c"#{dl_path}.part"
)
@ -298,18 +293,32 @@ defmodule Algora.Admin do
def download_video(video, dir) do
playlists = get_media_playlists(video)
video_playlist = case playlists do
%{@video_track => playlist} -> playlist
%{"video_master.m3u8" => playlist} -> playlist
end
video_chunks =
for n <- playlists.video.timeline,
for n <- video_playlist.timeline,
Map.has_key?(n, :uri),
do: n.uri
audio_playlist = case playlists do
%{@video_track => playlist} -> nil
%{@audio_track => playlist} -> playlist
%{"audio_master.m3u8" => playlist} -> playlist
end
audio_chunks =
for n <- playlists.audio.timeline,
Map.has_key?(n, :uri),
do: n.uri
if audio_playlist do
for n <- audio_playlist.timeline,
Map.has_key?(n, :uri),
do: n.uri
else
[]
end
{time, _} = :timer.tc(&download_chunks/2, [video_chunks ++ audio_chunks, dir])
{time, _} = :timer.tc(&download_chunks/3, [video_chunks ++ audio_chunks, dir, video.url_root])
video_chunks
|> Enum.map(fn chunk -> "#{dir}/#{chunk}" end)
@ -326,12 +335,12 @@ defmodule Algora.Admin do
"-y",
"-i",
"#{dir}/video.mp4",
"-i",
"#{dir}/audio.mp4",
(if audio_playlist, do: "-i"),
(if audio_playlist, do: "#{dir}/audio.mp4"),
"-c",
"copy",
"#{dir}/output.mp4"
]
] |> Enum.reject(&is_nil/1)
)
%File.Stat{size: size} = File.stat!("#{dir}/output.mp4")

View File

@ -1,10 +1,6 @@
defmodule Algora.Clipper do
alias Algora.{Storage, Library}
def clip(video, from, to) do
clip_timelines(video, from, to) |> List.first() |> elem(0)
end
def create_clip(video, from, to) do
uuid = Ecto.UUID.generate()
@ -34,6 +30,10 @@ defmodule Algora.Clipper do
"ffmpeg -i \"#{url}\" -ss #{ss} -t #{to - from} \"#{filename}.mp4\""
end
def clip(video, from, to) do
clip_timelines(video, from, to) |> List.first() |> elem(0)
end
def clip_timelines(video, from, to) do
playlists = Algora.Admin.get_media_playlists(video)
Enum.map(playlists, fn({manifest_name, playlist}) ->
@ -101,14 +101,16 @@ defmodule Algora.Clipper do
def trim_manifest(video, from, to) do
uuid = Ecto.UUID.generate()
%{playlist: playlist, ss: ss} = clip(video, from, to)
[{_manifet_name, %{ss: ss}}|_] = playlists = clip_timelines(video, from, to)
manifest = "#{ExM3U8.serialize(playlist)}#EXT-X-ENDLIST\n"
Enum.each(playlists, fn({manifest_name, %{playlist: playlist, ss: ss}}) ->
manifest = "#{ExM3U8.serialize(playlist)}#EXT-X-ENDLIST\n"
{:ok, _} =
Storage.upload(manifest, "clips/#{uuid}/g3cFdmlkZW8.m3u8",
content_type: "application/x-mpegURL"
)
{:ok, _} =
Storage.upload(manifest, "clips/#{uuid}/#{manifest_name}",
content_type: "application/x-mpegURL"
)
end)
{:ok, _} =
ExAws.S3.put_object_copy(