Support absolute file path in playlist_name

Fixes #585.

Change-Id: Icd0bc97a0b210c22a2dab716542d993a69d3d081
This commit is contained in:
KongQun Yang 2019-04-30 15:29:37 -07:00
parent ac616f36e4
commit adc3c804a9
4 changed files with 60 additions and 34 deletions

View File

@ -61,7 +61,8 @@ class MediaPlaylist {
};
/// @param hls_params contains HLS parameters.
/// @param file_name is the file name of this media playlist.
/// @param file_name is the file name of this media playlist, relative to
/// master playlist output path.
/// @param name is the name of this playlist. In other words this is the
/// value of the NAME attribute for EXT-X-MEDIA. This is not
/// necessarily the same as @a file_name.

View File

@ -281,7 +281,7 @@ SimpleHlsNotifier::SimpleHlsNotifier(const HlsParams& hls_params)
media_playlist_factory_(new MediaPlaylistFactory()) {
const base::FilePath master_playlist_path(
base::FilePath::FromUTF8Unsafe(hls_params.master_playlist_output));
output_dir_ = master_playlist_path.DirName().AsUTF8Unsafe();
master_playlist_dir_ = master_playlist_path.DirName().AsUTF8Unsafe();
const std::string& default_audio_langauge = hls_params.default_language;
const std::string& default_text_language =
hls_params.default_text_language.empty()
@ -305,11 +305,14 @@ bool SimpleHlsNotifier::NotifyNewStream(const MediaInfo& media_info,
uint32_t* stream_id) {
DCHECK(stream_id);
const std::string relative_playlist_path = MakePathRelative(
playlist_name, FilePath::FromUTF8Unsafe(master_playlist_dir_));
std::unique_ptr<MediaPlaylist> media_playlist =
media_playlist_factory_->Create(hls_params(), playlist_name, name,
group_id);
media_playlist_factory_->Create(hls_params(), relative_playlist_path,
name, group_id);
MediaInfo adjusted_media_info = MakeMediaInfoPathsRelativeToPlaylist(
media_info, hls_params().base_url, output_dir_,
media_info, hls_params().base_url, master_playlist_dir_,
media_playlist->file_name());
if (!media_playlist->SetMediaInfo(adjusted_media_info)) {
LOG(ERROR) << "Failed to set media info for playlist " << playlist_name;
@ -353,8 +356,8 @@ bool SimpleHlsNotifier::NotifyNewSegment(uint32_t stream_id,
}
auto& media_playlist = stream_iterator->second->media_playlist;
const std::string& segment_url =
GenerateSegmentUrl(segment_name, hls_params().base_url, output_dir_,
media_playlist->file_name());
GenerateSegmentUrl(segment_name, hls_params().base_url,
master_playlist_dir_, media_playlist->file_name());
media_playlist->AddSegment(segment_url, start_time, duration,
start_byte_offset, size);
@ -374,15 +377,15 @@ bool SimpleHlsNotifier::NotifyNewSegment(uint32_t stream_id,
if (target_duration_updated) {
for (MediaPlaylist* playlist : media_playlists_) {
playlist->SetTargetDuration(target_duration_);
if (!WriteMediaPlaylist(output_dir_, playlist))
if (!WriteMediaPlaylist(master_playlist_dir_, playlist))
return false;
}
} else {
if (!WriteMediaPlaylist(output_dir_, media_playlist.get()))
if (!WriteMediaPlaylist(master_playlist_dir_, media_playlist.get()))
return false;
}
if (!master_playlist_->WriteMasterPlaylist(hls_params().base_url,
output_dir_, media_playlists_)) {
if (!master_playlist_->WriteMasterPlaylist(
hls_params().base_url, master_playlist_dir_, media_playlists_)) {
LOG(ERROR) << "Failed to write master playlist.";
return false;
}
@ -482,11 +485,11 @@ bool SimpleHlsNotifier::Flush() {
base::AutoLock auto_lock(lock_);
for (MediaPlaylist* playlist : media_playlists_) {
playlist->SetTargetDuration(target_duration_);
if (!WriteMediaPlaylist(output_dir_, playlist))
if (!WriteMediaPlaylist(master_playlist_dir_, playlist))
return false;
}
if (!master_playlist_->WriteMasterPlaylist(hls_params().base_url, output_dir_,
media_playlists_)) {
if (!master_playlist_->WriteMasterPlaylist(
hls_params().base_url, master_playlist_dir_, media_playlists_)) {
LOG(ERROR) << "Failed to write master playlist.";
return false;
}

View File

@ -77,7 +77,7 @@ class SimpleHlsNotifier : public HlsNotifier {
MediaPlaylist::EncryptionMethod encryption_method;
};
std::string output_dir_;
std::string master_playlist_dir_;
uint32_t target_duration_ = 0;
std::unique_ptr<MediaPlaylistFactory> media_playlist_factory_;

View File

@ -379,6 +379,8 @@ struct RebaseUrlTestData {
std::string master_playlist_dir;
// Media playlist path. This may be relative or absolute.
std::string playlist_path;
// Expected relative playlist path. It is path_relative_to(master_directory).
std::string expected_relative_playlist_path;
// Media segment path. This may be relative or absolute.
std::string segment_path;
// Expected segment URL in the media playlist:
@ -421,7 +423,7 @@ TEST_P(SimpleHlsNotifierRebaseUrlTest, Test) {
// Pointer released by SimpleHlsNotifier.
MockMediaPlaylist* mock_media_playlist =
new MockMediaPlaylist(test_data_.playlist_path, "", "");
new MockMediaPlaylist(test_data_.expected_relative_playlist_path, "", "");
EXPECT_CALL(
*mock_media_playlist,
@ -433,8 +435,9 @@ TEST_P(SimpleHlsNotifierRebaseUrlTest, Test) {
EXPECT_CALL(*mock_media_playlist,
AddSegment(test_data_.expected_segment_url, _, _, _, _));
}
EXPECT_CALL(*factory, CreateMock(_, StrEq(test_data_.playlist_path),
StrEq("name"), StrEq("groupid")))
EXPECT_CALL(*factory,
CreateMock(_, StrEq(test_data_.expected_relative_playlist_path),
StrEq("name"), StrEq("groupid")))
.WillOnce(Return(mock_media_playlist));
InjectMasterPlaylist(std::move(mock_master_playlist), &test_notifier);
@ -459,35 +462,54 @@ INSTANTIATE_TEST_CASE_P(
SimpleHlsNotifierRebaseUrlTest,
::testing::Values(
// Verify relative segment path.
RebaseUrlTestData{
"http://testprefix.com/", "master_directory/",
"video_playlist.m3u8", "master_directory/path/to/media1.ts",
"http://testprefix.com/path/to/media1.ts",
"" /* init segment path */, "" /* expected init segment url */},
RebaseUrlTestData{"http://testprefix.com/", "master_directory/",
"video_playlist.m3u8", "video_playlist.m3u8",
"master_directory/path/to/media1.ts",
"http://testprefix.com/path/to/media1.ts",
"" /* init segment path */,
"" /* expected init segment url */},
// Verify relative init segment path.
RebaseUrlTestData{"http://testprefix.com/", "master_directory/",
"video_playlist.m3u8", "" /* segment path */,
"" /* expected segment url */,
"video_playlist.m3u8", "video_playlist.m3u8",
"" /* segment path */, "" /* expected segment url */,
"master_directory/path/to/init.mp4",
"http://testprefix.com/path/to/init.mp4"},
// Verify segment url relative to playlist.
RebaseUrlTestData{
"" /* no base_url */, "master_directory/",
"video/video_playlist.m3u8",
"" /* no base url */, "master_directory/",
"video/video_playlist.m3u8", "video/video_playlist.m3u8",
"master_directory/video/path/to/media1.m4s", "path/to/media1.m4s",
"master_directory/video/path/to/init.mp4", "path/to/init.mp4"},
// Verify absolute directory.
RebaseUrlTestData{
"http://testprefix.com/", "/tmp/something/", "video_playlist.m3u8",
"/tmp/something/media1.ts", "http://testprefix.com/media1.ts",
"" /* init segment path */, "" /* expected init segment url */},
"video_playlist.m3u8", "/tmp/something/media1.ts",
"http://testprefix.com/media1.ts", "" /* init segment path */,
"" /* expected init segment url */},
// Verify absolute directory, but media in a different directory.
// Note that we don't really expect this in practice.
RebaseUrlTestData{"http://testprefix.com/", "/tmp/something/",
"video_playlist.m3u8", "/var/somewhereelse/media1.ts",
"http://testprefix.com//var/somewhereelse/media1.ts",
"" /* init segment path */,
"" /* expected init segment url */}));
RebaseUrlTestData{
"http://testprefix.com/", "/tmp/something/", "video_playlist.m3u8",
"video_playlist.m3u8", "/var/somewhereelse/media1.ts",
"http://testprefix.com//var/somewhereelse/media1.ts",
"" /* init segment path */, "" /* expected init segment url */
},
// Verify absolute directory, absolute media playlist path.
RebaseUrlTestData{
"http://testprefix.com/", "/tmp/something/",
"/tmp/something/video/video_playlist.m3u8",
"video/video_playlist.m3u8", "/tmp/something/video/media1.ts",
"http://testprefix.com/video/media1.ts", "" /* init segment path */,
"" /* expected init segment url */
},
// Same as above, but without base_url.
RebaseUrlTestData{
"" /* no base url */, "/tmp/something/",
"/tmp/something/video/video_playlist.m3u8",
"video/video_playlist.m3u8", "/tmp/something/video/media1.ts",
"media1.ts", "" /* init segment path */,
"" /* expected init segment url */
}));
class LiveOrEventSimpleHlsNotifierTest
: public SimpleHlsNotifierTest,