+}
+
+
+FFmpegContent::FFmpegContent (vector<shared_ptr<Content>> c)
+ : Content (c)
+{
+ auto i = c.begin ();
+
+ bool need_video = false;
+ bool need_audio = false;
+ bool need_text = false;
+
+ if (i != c.end ()) {
+ need_video = static_cast<bool> ((*i)->video);
+ need_audio = static_cast<bool> ((*i)->audio);
+ need_text = !(*i)->text.empty();
+ }
+
+ while (i != c.end ()) {
+ if (need_video != static_cast<bool> ((*i)->video)) {
+ throw JoinError (_("Content to be joined must all have or not have video"));
+ }
+ if (need_audio != static_cast<bool> ((*i)->audio)) {
+ throw JoinError (_("Content to be joined must all have or not have audio"));
+ }
+ if (need_text != !(*i)->text.empty()) {
+ throw JoinError (_("Content to be joined must all have or not have subtitles or captions"));
+ }
+ ++i;
+ }
+
+ if (need_video) {
+ video = make_shared<VideoContent>(this, c);
+ }
+ if (need_audio) {
+ audio = make_shared<AudioContent>(this, c);
+ }
+ if (need_text) {
+ text.push_back (make_shared<TextContent>(this, c));
+ }
+
+ auto ref = dynamic_pointer_cast<FFmpegContent> (c[0]);
+ DCPOMATIC_ASSERT (ref);
+
+ for (size_t i = 0; i < c.size(); ++i) {
+ auto fc = dynamic_pointer_cast<FFmpegContent>(c[i]);
+ if (fc->only_text() && fc->only_text()->use() && *(fc->_subtitle_stream.get()) != *(ref->_subtitle_stream.get())) {
+ throw JoinError (_("Content to be joined must use the same subtitle stream."));
+ }
+ }
+
+ /* XXX: should probably check that more of the stuff below is the same in *this and ref */