Copy audio language when setting up a project from a DCP (#3009).
authorCarl Hetherington <cth@carlh.net>
Fri, 28 Mar 2025 00:21:28 +0000 (01:21 +0100)
committerCarl Hetherington <cth@carlh.net>
Fri, 28 Mar 2025 00:21:28 +0000 (01:21 +0100)
src/lib/copy_dcp_details_to_film.cc
src/lib/dcp_content.cc
src/lib/dcp_content.h
test/copy_dcp_details_to_film_test.cc [new file with mode: 0644]
test/wscript

index 32b08d0625997d4def1b38b33a28aeb69a583a24..9e0ad79c1d3cfe295c33e3395511aa550f4a5b9e 100644 (file)
@@ -61,6 +61,7 @@ copy_dcp_settings_to_film(shared_ptr<const DCPContent> dcp, shared_ptr<Film> fil
 
        if (dcp->audio) {
                film->set_audio_channels(dcp->audio->stream()->channels());
+               film->set_audio_language(dcp->audio_language());
        }
 
        film->set_ratings(dcp->ratings());
index 32b97b06f1b9443e7eb5b10d9ff3a4d5e867ea47..885cbad931652932891b0f6fefdb2df1781120f9 100644 (file)
@@ -168,6 +168,9 @@ DCPContent::DCPContent(cxml::ConstNodePtr node, boost::optional<boost::filesyste
        }
 
        _active_audio_channels = node->optional_number_child<int>("ActiveAudioChannels");
+       if (auto lang = node->optional_string_child("AudioLanguage")) {
+               _audio_language = dcp::LanguageTag(*lang);
+       }
 
        for (auto non_zero: node->node_children("HasNonZeroEntryPoint")) {
                try {
@@ -273,6 +276,7 @@ DCPContent::examine(shared_ptr<const Film> film, shared_ptr<Job> job, bool toler
                as->set_mapping (m);
 
                _active_audio_channels = examiner->active_audio_channels();
+               _audio_language = examiner->audio_language();
        }
 
        if (examiner->has_atmos()) {
@@ -458,6 +462,10 @@ DCPContent::as_xml(xmlpp::Element* element, bool with_paths, PathBehaviour path_
                cxml::add_text_child(element, "ActiveAudioChannels", fmt::to_string(*_active_audio_channels));
        }
 
+       if (_audio_language) {
+               cxml::add_text_child(element, "AudioLanguage", _audio_language->as_string());
+       }
+
        for (auto i = 0; i < static_cast<int>(TextType::COUNT); ++i) {
                if (_has_non_zero_entry_point[i]) {
                        auto has = cxml::add_child(element, "HasNonZeroEntryPoint");
index 8545adf063e987b7da258500d80b41d2e0ac78f6..a0a18703a458763231440f7d657159185d630ffe 100644 (file)
@@ -36,6 +36,7 @@
 #include <libcxml/cxml.h>
 #include <dcp/content_kind.h>
 #include <dcp/encrypted_kdm.h>
+#include <dcp/language_tag.h>
 #include <dcp/rating.h>
 
 
@@ -191,6 +192,13 @@ public:
 
        int active_audio_channels() const;
 
+       /** @return a guess of the DCP's audio language; if there are multiple reels,
+        *  and they have different langauges, this could be wrong.
+        */
+       boost::optional<dcp::LanguageTag> audio_language () const {
+               return _audio_language;
+       }
+
        void check_font_ids();
 
 private:
@@ -241,6 +249,7 @@ private:
        EnumIndexedVector<bool, TextType> _has_non_zero_entry_point;
 
        boost::optional<int> _active_audio_channels;
+       boost::optional<dcp::LanguageTag> _audio_language;
 };
 
 
diff --git a/test/copy_dcp_details_to_film_test.cc b/test/copy_dcp_details_to_film_test.cc
new file mode 100644 (file)
index 0000000..6dd913a
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+    Copyright (C) 2025 Carl Hetherington <cth@carlh.net>
+
+    This file is part of DCP-o-matic.
+
+    DCP-o-matic is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    DCP-o-matic is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include "lib/content_factory.h"
+#include "lib/copy_dcp_details_to_film.h"
+#include "lib/dcp_content.h"
+#include "lib/film.h"
+#include "test.h"
+#include <dcp/language_tag.h>
+#include <boost/test/unit_test.hpp>
+
+
+using std::make_shared;
+
+
+BOOST_AUTO_TEST_CASE(copy_audio_language_to_film)
+{
+       auto content = content_factory("test/data/sine_440.wav")[0];
+       auto film1 = new_test_film("copy_audio_language_to_film1", { content });
+       film1->set_audio_language(dcp::LanguageTag("de-DE"));
+       make_and_verify_dcp(
+               film1,
+               {
+                       dcp::VerificationNote::Code::MISSING_CPL_METADATA
+               });
+
+       auto dcp = make_shared<DCPContent>(film1->dir(film1->dcp_name()));
+       auto film2 = new_test_film("copy_audio_language_to_film2", { dcp });
+       copy_dcp_settings_to_film(dcp, film2);
+
+       BOOST_REQUIRE(film2->audio_language());
+       BOOST_CHECK_EQUAL(film2->audio_language()->as_string(), "de-DE");
+}
+
index 868d98c5829e567242901e7cda60b30f0dff0b99..b568872a3975b23426b53ac748349823ccda911d 100644 (file)
@@ -70,6 +70,7 @@ def build(bld):
                  colour_conversion_test.cc
                  config_test.cc
                  content_test.cc
+                 copy_dcp_details_to_film_test.cc
                  cpl_hash_test.cc
                  cpl_metadata_test.cc
                  create_cli_test.cc