From 9cd139cb404af807a056a442bd910f9bfac2e6ba Mon Sep 17 00:00:00 2001 From: trueChazza Date: Fri, 9 Feb 2024 16:01:27 +1300 Subject: [PATCH] fix: fix keyframes --- lib/hls_playlist.ex | 24 +++++++------ test/hls_playlist_test.exs | 69 ++++++++++++-------------------------- 2 files changed, 35 insertions(+), 58 deletions(-) diff --git a/lib/hls_playlist.ex b/lib/hls_playlist.ex index 5d94cc5..f0bc460 100644 --- a/lib/hls_playlist.ex +++ b/lib/hls_playlist.ex @@ -34,7 +34,13 @@ defmodule HlsPlaylist do |> Enum.filter(fn x -> String.contains?(x, "K__") end) end) |> Enum.reject(fn x -> Enum.empty?(x) end) - |> Enum.map(fn x -> String.trim_leading(Enum.at(x, 0), "packet,") end) + |> Enum.map(fn x -> + String.trim_leading(Enum.at(x, 0), "packet,") + |> String.trim_trailing(",K__") + |> String.split(",") + |> Kernel.hd() + |> String.to_float + end) end def get_segments(keyframes, duration, segment_length) do @@ -54,12 +60,12 @@ defmodule HlsPlaylist do end kf_distance = kf - last_segment - kf_distance_from_desire = abs(desired_segment_length - kf_distance) + kf_distance_from_desire = Kernel.abs(desired_segment_length - kf_distance) kf_next_distance_from_desire = case {kf_next, kf_next_distance} do {nil, _} -> nil - {_next_kf, next_distance} -> abs(desired_segment_length - next_distance) + {_next_kf, next_distance} -> Kernel.abs(desired_segment_length - next_distance) end cond do @@ -84,26 +90,24 @@ defmodule HlsPlaylist do end def get_playlist(segment_lengths, segment_name) do - {playlist_segments, largest_segment} = + {segments, largest_segment} = Enum.reduce(segment_lengths, {[], 0.0}, fn segl, {acc, current_largest} -> largest_segment = max(segl, current_largest) - playlist_segment = + extinf_segment = "#EXTINF:#{String.Chars.to_string(segl)},\n#{segment_name}#{length(acc)}.ts" - {[playlist_segment | acc], largest_segment} + {[extinf_segment | acc], largest_segment} end) - largest_segment_rounded = trunc(Float.floor(largest_segment)) - """ #EXTM3U #EXT-X-VERSION:3 #EXT-X-ALLOW-CACHE:NO - #EXT-X-TARGETDURATION:#{largest_segment_rounded} + #EXT-X-TARGETDURATION:#{Kernel.trunc(Float.floor(largest_segment))} #EXT-X-MEDIA-SEQUENCE:0 #EXT-X-PLAYLIST-TYPE:VOD - #{Enum.join(Enum.reverse(playlist_segments), "\n")} + #{Enum.join(Enum.reverse(segments), "\n")} #EXT-X-ENDLIST\ """ end diff --git a/test/hls_playlist_test.exs b/test/hls_playlist_test.exs index 03de8a4..e6f04a7 100644 --- a/test/hls_playlist_test.exs +++ b/test/hls_playlist_test.exs @@ -2,39 +2,27 @@ defmodule HlsPlaylistTest do use ExUnit.Case doctest HlsPlaylist + @media_path "dev/sample__1080__libx264__ac3__30s__video.mp4" + test "get_duration" do - assert HlsPlaylist.get_duration("dev/sample__1080__libx264__ac3__30s__video.mp4") == 30.0 + assert HlsPlaylist.get_duration(@media_path) == 30.0 end test "get_keyframes" do - assert HlsPlaylist.get_keyframes("dev/sample__1080__libx264__ac3__30s__video.mp4") == [ - "0.000000,-0.033333,K__", - "4.166667,4.133333,K__", - "8.333333,8.300000,K__", - "12.500000,12.466667,K__", - "16.266667,16.233333,K__", - "20.133333,20.100000,K__", - "24.300000,24.266667,K__", - "27.433333,27.400000,K__" + assert HlsPlaylist.get_keyframes(@media_path) == [ + 0.0, + 4.166667, + 8.333333, + 12.5, + 16.266667, + 20.133333, + 24.3, + 27.433333 ] end test "get_segments" do - keyframes = [ - 0.000000, - 4.166667, - 8.333333, - 12.500000, - 16.266667, - 20.133333, - 24.300000, - 27.433333 - ] - - duration = 30.0 - segment_length = 3 - - assert HlsPlaylist.get_segments(keyframes, duration, segment_length) == + assert HlsPlaylist.get_segments(HlsPlaylist.get_keyframes(@media_path), HlsPlaylist.get_duration(@media_path), 3) == [ 4.166667, 4.166666, @@ -48,28 +36,15 @@ defmodule HlsPlaylistTest do end test "get_playlist" do - segment_lengths = - [ - 4.166667, - 4.166666, - 4.166667, - 3.766667, - 3.866666, - 4.166667, - 3.133333, - 2.566667 - ] + assert HlsPlaylist.get_playlist(HlsPlaylist.get_segments(HlsPlaylist.get_keyframes(@media_path), HlsPlaylist.get_duration(@media_path), 3), "segment") == - segment_name = "segment" - - # a little off from ffmpeg-generated.m3u8 - # - # #EXTINF:4.166666, should be #EXTINF:4.166667 - # segment1.ts - # - # #EXTINF:3.866666, should be #EXTINF:3.866667 - # segment4.ts - expected_playlist = + # a little off from generated-ffmpeg.m3u8 + # + # #EXTINF:4.166666, should be #EXTINF:4.166667 + # segment1.ts + # + # #EXTINF:3.866666, should be #EXTINF:3.866667 + # segment4.ts """ #EXTM3U #EXT-X-VERSION:3 @@ -95,7 +70,5 @@ defmodule HlsPlaylistTest do segment7.ts #EXT-X-ENDLIST\ """ - - assert HlsPlaylist.get_playlist(segment_lengths, segment_name) == expected_playlist end end