DASH Media Packaging SDK
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator
mpd_generator.cc
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/app/mpd_generator_flags.h"
8 #include "packager/app/vlog_flags.h"
9 #include "packager/base/at_exit.h"
10 #include "packager/base/command_line.h"
11 #include "packager/base/logging.h"
12 #include "packager/base/strings/string_split.h"
13 #include "packager/base/strings/stringprintf.h"
14 #include "packager/mpd/util/mpd_writer.h"
15 #include "packager/version/version.h"
16 
17 namespace shaka {
18 namespace {
19 const char kUsage[] =
20  "MPD generation driver program.\n"
21  "This program accepts MediaInfo files in human readable text "
22  "format and outputs an MPD.\n"
23  "The main use case for this is to output MPD for VOD.\n"
24  "Limitations:\n"
25  " Each MediaInfo can only have one of VideoInfo, AudioInfo, or TextInfo.\n"
26  " There will be at most 3 AdaptationSets in the MPD, i.e. 1 video, 1 "
27  "audio, and 1 text.\n"
28  "Sample Usage:\n"
29  "%s --input=\"video1.media_info,video2.media_info,audio1.media_info\" "
30  "--output=\"video_audio.mpd\"";
31 
32 enum ExitStatus {
33  kSuccess = 0,
34  kEmptyInputError,
35  kEmptyOutputError,
36  kFailedToWriteMpdToFileError
37 };
38 
39 ExitStatus CheckRequiredFlags() {
40  if (FLAGS_input.empty()) {
41  LOG(ERROR) << "--input is required.";
42  return kEmptyInputError;
43  }
44 
45  if (FLAGS_output.empty()) {
46  LOG(ERROR) << "--output is required.";
47  return kEmptyOutputError;
48  }
49 
50  return kSuccess;
51 }
52 
53 ExitStatus RunMpdGenerator() {
54  DCHECK_EQ(CheckRequiredFlags(), kSuccess);
55  std::vector<std::string> base_urls;
56  std::vector<std::string> input_files;
57  typedef std::vector<std::string>::const_iterator Iterator;
58 
59  base::SplitString(FLAGS_input, ',', &input_files);
60 
61  if (!FLAGS_base_urls.empty()) {
62  base::SplitString(FLAGS_base_urls, ',', &base_urls);
63  }
64 
65  MpdWriter mpd_writer;
66  for (Iterator it = base_urls.begin(); it != base_urls.end(); ++it)
67  mpd_writer.AddBaseUrl(*it);
68 
69  for (Iterator it = input_files.begin(); it != input_files.end(); ++it) {
70  if (!mpd_writer.AddFile(it->c_str(), FLAGS_output)) {
71  LOG(WARNING) << "MpdWriter failed to read " << *it << ", skipping.";
72  }
73  }
74 
75  if (!mpd_writer.WriteMpdToFile(FLAGS_output.c_str())) {
76  LOG(ERROR) << "Failed to write MPD to " << FLAGS_output;
77  return kFailedToWriteMpdToFileError;
78  }
79 
80  return kSuccess;
81 }
82 
83 int MpdMain(int argc, char** argv) {
84  base::AtExitManager exit;
85  // Needed to enable VLOG/DVLOG through --vmodule or --v.
86  base::CommandLine::Init(argc, argv);
87  CHECK(logging::InitLogging(logging::LoggingSettings()));
88 
89  google::SetUsageMessage(base::StringPrintf(kUsage, argv[0]));
90  google::ParseCommandLineFlags(&argc, &argv, true);
91 
92  ExitStatus status = CheckRequiredFlags();
93  if (status != kSuccess) {
94  std::string version_string =
95  base::StringPrintf("mpd_generator version %s", kPackagerVersion);
96  google::ShowUsageWithFlags(version_string.c_str());
97  return status;
98  }
99 
100  return RunMpdGenerator();
101 }
102 
103 } // namespace
104 } // namespace shaka
105 
106 int main(int argc, char** argv) {
107  return shaka::MpdMain(argc, argv);
108 }