Support absolute file path in playlist_name
Fixes #585. Change-Id: Icd0bc97a0b210c22a2dab716542d993a69d3d081
This commit is contained in:
parent
ac616f36e4
commit
adc3c804a9
|
@ -61,7 +61,8 @@ class MediaPlaylist {
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @param hls_params contains HLS parameters.
|
/// @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
|
/// @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
|
/// value of the NAME attribute for EXT-X-MEDIA. This is not
|
||||||
/// necessarily the same as @a file_name.
|
/// necessarily the same as @a file_name.
|
||||||
|
|
|
@ -281,7 +281,7 @@ SimpleHlsNotifier::SimpleHlsNotifier(const HlsParams& hls_params)
|
||||||
media_playlist_factory_(new MediaPlaylistFactory()) {
|
media_playlist_factory_(new MediaPlaylistFactory()) {
|
||||||
const base::FilePath master_playlist_path(
|
const base::FilePath master_playlist_path(
|
||||||
base::FilePath::FromUTF8Unsafe(hls_params.master_playlist_output));
|
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_audio_langauge = hls_params.default_language;
|
||||||
const std::string& default_text_language =
|
const std::string& default_text_language =
|
||||||
hls_params.default_text_language.empty()
|
hls_params.default_text_language.empty()
|
||||||
|
@ -305,11 +305,14 @@ bool SimpleHlsNotifier::NotifyNewStream(const MediaInfo& media_info,
|
||||||
uint32_t* stream_id) {
|
uint32_t* stream_id) {
|
||||||
DCHECK(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 =
|
std::unique_ptr<MediaPlaylist> media_playlist =
|
||||||
media_playlist_factory_->Create(hls_params(), playlist_name, name,
|
media_playlist_factory_->Create(hls_params(), relative_playlist_path,
|
||||||
group_id);
|
name, group_id);
|
||||||
MediaInfo adjusted_media_info = MakeMediaInfoPathsRelativeToPlaylist(
|
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());
|
media_playlist->file_name());
|
||||||
if (!media_playlist->SetMediaInfo(adjusted_media_info)) {
|
if (!media_playlist->SetMediaInfo(adjusted_media_info)) {
|
||||||
LOG(ERROR) << "Failed to set media info for playlist " << playlist_name;
|
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;
|
auto& media_playlist = stream_iterator->second->media_playlist;
|
||||||
const std::string& segment_url =
|
const std::string& segment_url =
|
||||||
GenerateSegmentUrl(segment_name, hls_params().base_url, output_dir_,
|
GenerateSegmentUrl(segment_name, hls_params().base_url,
|
||||||
media_playlist->file_name());
|
master_playlist_dir_, media_playlist->file_name());
|
||||||
media_playlist->AddSegment(segment_url, start_time, duration,
|
media_playlist->AddSegment(segment_url, start_time, duration,
|
||||||
start_byte_offset, size);
|
start_byte_offset, size);
|
||||||
|
|
||||||
|
@ -374,15 +377,15 @@ bool SimpleHlsNotifier::NotifyNewSegment(uint32_t stream_id,
|
||||||
if (target_duration_updated) {
|
if (target_duration_updated) {
|
||||||
for (MediaPlaylist* playlist : media_playlists_) {
|
for (MediaPlaylist* playlist : media_playlists_) {
|
||||||
playlist->SetTargetDuration(target_duration_);
|
playlist->SetTargetDuration(target_duration_);
|
||||||
if (!WriteMediaPlaylist(output_dir_, playlist))
|
if (!WriteMediaPlaylist(master_playlist_dir_, playlist))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!WriteMediaPlaylist(output_dir_, media_playlist.get()))
|
if (!WriteMediaPlaylist(master_playlist_dir_, media_playlist.get()))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!master_playlist_->WriteMasterPlaylist(hls_params().base_url,
|
if (!master_playlist_->WriteMasterPlaylist(
|
||||||
output_dir_, media_playlists_)) {
|
hls_params().base_url, master_playlist_dir_, media_playlists_)) {
|
||||||
LOG(ERROR) << "Failed to write master playlist.";
|
LOG(ERROR) << "Failed to write master playlist.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -482,11 +485,11 @@ bool SimpleHlsNotifier::Flush() {
|
||||||
base::AutoLock auto_lock(lock_);
|
base::AutoLock auto_lock(lock_);
|
||||||
for (MediaPlaylist* playlist : media_playlists_) {
|
for (MediaPlaylist* playlist : media_playlists_) {
|
||||||
playlist->SetTargetDuration(target_duration_);
|
playlist->SetTargetDuration(target_duration_);
|
||||||
if (!WriteMediaPlaylist(output_dir_, playlist))
|
if (!WriteMediaPlaylist(master_playlist_dir_, playlist))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!master_playlist_->WriteMasterPlaylist(hls_params().base_url, output_dir_,
|
if (!master_playlist_->WriteMasterPlaylist(
|
||||||
media_playlists_)) {
|
hls_params().base_url, master_playlist_dir_, media_playlists_)) {
|
||||||
LOG(ERROR) << "Failed to write master playlist.";
|
LOG(ERROR) << "Failed to write master playlist.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ class SimpleHlsNotifier : public HlsNotifier {
|
||||||
MediaPlaylist::EncryptionMethod encryption_method;
|
MediaPlaylist::EncryptionMethod encryption_method;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string output_dir_;
|
std::string master_playlist_dir_;
|
||||||
uint32_t target_duration_ = 0;
|
uint32_t target_duration_ = 0;
|
||||||
|
|
||||||
std::unique_ptr<MediaPlaylistFactory> media_playlist_factory_;
|
std::unique_ptr<MediaPlaylistFactory> media_playlist_factory_;
|
||||||
|
|
|
@ -379,6 +379,8 @@ struct RebaseUrlTestData {
|
||||||
std::string master_playlist_dir;
|
std::string master_playlist_dir;
|
||||||
// Media playlist path. This may be relative or absolute.
|
// Media playlist path. This may be relative or absolute.
|
||||||
std::string playlist_path;
|
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.
|
// Media segment path. This may be relative or absolute.
|
||||||
std::string segment_path;
|
std::string segment_path;
|
||||||
// Expected segment URL in the media playlist:
|
// Expected segment URL in the media playlist:
|
||||||
|
@ -421,7 +423,7 @@ TEST_P(SimpleHlsNotifierRebaseUrlTest, Test) {
|
||||||
|
|
||||||
// Pointer released by SimpleHlsNotifier.
|
// Pointer released by SimpleHlsNotifier.
|
||||||
MockMediaPlaylist* mock_media_playlist =
|
MockMediaPlaylist* mock_media_playlist =
|
||||||
new MockMediaPlaylist(test_data_.playlist_path, "", "");
|
new MockMediaPlaylist(test_data_.expected_relative_playlist_path, "", "");
|
||||||
|
|
||||||
EXPECT_CALL(
|
EXPECT_CALL(
|
||||||
*mock_media_playlist,
|
*mock_media_playlist,
|
||||||
|
@ -433,7 +435,8 @@ TEST_P(SimpleHlsNotifierRebaseUrlTest, Test) {
|
||||||
EXPECT_CALL(*mock_media_playlist,
|
EXPECT_CALL(*mock_media_playlist,
|
||||||
AddSegment(test_data_.expected_segment_url, _, _, _, _));
|
AddSegment(test_data_.expected_segment_url, _, _, _, _));
|
||||||
}
|
}
|
||||||
EXPECT_CALL(*factory, CreateMock(_, StrEq(test_data_.playlist_path),
|
EXPECT_CALL(*factory,
|
||||||
|
CreateMock(_, StrEq(test_data_.expected_relative_playlist_path),
|
||||||
StrEq("name"), StrEq("groupid")))
|
StrEq("name"), StrEq("groupid")))
|
||||||
.WillOnce(Return(mock_media_playlist));
|
.WillOnce(Return(mock_media_playlist));
|
||||||
|
|
||||||
|
@ -459,35 +462,54 @@ INSTANTIATE_TEST_CASE_P(
|
||||||
SimpleHlsNotifierRebaseUrlTest,
|
SimpleHlsNotifierRebaseUrlTest,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
// Verify relative segment path.
|
// Verify relative segment path.
|
||||||
RebaseUrlTestData{
|
RebaseUrlTestData{"http://testprefix.com/", "master_directory/",
|
||||||
"http://testprefix.com/", "master_directory/",
|
"video_playlist.m3u8", "video_playlist.m3u8",
|
||||||
"video_playlist.m3u8", "master_directory/path/to/media1.ts",
|
"master_directory/path/to/media1.ts",
|
||||||
"http://testprefix.com/path/to/media1.ts",
|
"http://testprefix.com/path/to/media1.ts",
|
||||||
"" /* init segment path */, "" /* expected init segment url */},
|
"" /* init segment path */,
|
||||||
|
"" /* expected init segment url */},
|
||||||
// Verify relative init segment path.
|
// Verify relative init segment path.
|
||||||
RebaseUrlTestData{"http://testprefix.com/", "master_directory/",
|
RebaseUrlTestData{"http://testprefix.com/", "master_directory/",
|
||||||
"video_playlist.m3u8", "" /* segment path */,
|
"video_playlist.m3u8", "video_playlist.m3u8",
|
||||||
"" /* expected segment url */,
|
"" /* segment path */, "" /* expected segment url */,
|
||||||
"master_directory/path/to/init.mp4",
|
"master_directory/path/to/init.mp4",
|
||||||
"http://testprefix.com/path/to/init.mp4"},
|
"http://testprefix.com/path/to/init.mp4"},
|
||||||
// Verify segment url relative to playlist.
|
// Verify segment url relative to playlist.
|
||||||
RebaseUrlTestData{
|
RebaseUrlTestData{
|
||||||
"" /* no base_url */, "master_directory/",
|
"" /* no base url */, "master_directory/",
|
||||||
"video/video_playlist.m3u8",
|
"video/video_playlist.m3u8", "video/video_playlist.m3u8",
|
||||||
"master_directory/video/path/to/media1.m4s", "path/to/media1.m4s",
|
"master_directory/video/path/to/media1.m4s", "path/to/media1.m4s",
|
||||||
"master_directory/video/path/to/init.mp4", "path/to/init.mp4"},
|
"master_directory/video/path/to/init.mp4", "path/to/init.mp4"},
|
||||||
// Verify absolute directory.
|
// Verify absolute directory.
|
||||||
RebaseUrlTestData{
|
RebaseUrlTestData{
|
||||||
"http://testprefix.com/", "/tmp/something/", "video_playlist.m3u8",
|
"http://testprefix.com/", "/tmp/something/", "video_playlist.m3u8",
|
||||||
"/tmp/something/media1.ts", "http://testprefix.com/media1.ts",
|
"video_playlist.m3u8", "/tmp/something/media1.ts",
|
||||||
"" /* init segment path */, "" /* expected init segment url */},
|
"http://testprefix.com/media1.ts", "" /* init segment path */,
|
||||||
|
"" /* expected init segment url */},
|
||||||
// Verify absolute directory, but media in a different directory.
|
// Verify absolute directory, but media in a different directory.
|
||||||
// Note that we don't really expect this in practice.
|
// Note that we don't really expect this in practice.
|
||||||
RebaseUrlTestData{"http://testprefix.com/", "/tmp/something/",
|
RebaseUrlTestData{
|
||||||
|
"http://testprefix.com/", "/tmp/something/", "video_playlist.m3u8",
|
||||||
"video_playlist.m3u8", "/var/somewhereelse/media1.ts",
|
"video_playlist.m3u8", "/var/somewhereelse/media1.ts",
|
||||||
"http://testprefix.com//var/somewhereelse/media1.ts",
|
"http://testprefix.com//var/somewhereelse/media1.ts",
|
||||||
"" /* init segment path */,
|
"" /* init segment path */, "" /* expected init segment url */
|
||||||
"" /* 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
|
class LiveOrEventSimpleHlsNotifierTest
|
||||||
: public SimpleHlsNotifierTest,
|
: public SimpleHlsNotifierTest,
|
||||||
|
|
Loading…
Reference in New Issue