From 320c8ab29fbdbca7fc6fd8df5c024ca1e9004ea9 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Mon, 29 Apr 2019 14:08:31 +0200 Subject: [PATCH] Track selector and language code support backported from Pro edition --- lib/langcodes.cpp | 708 ++++++++++++++++++++++++++++++++++++- lib/langcodes.h | 2 + src/output/output.cpp | 79 +++++ src/output/output.h | 2 + src/output/output_http.cpp | 3 + 5 files changed, 792 insertions(+), 2 deletions(-) diff --git a/lib/langcodes.cpp b/lib/langcodes.cpp index 25a4e99c..497223e3 100644 --- a/lib/langcodes.cpp +++ b/lib/langcodes.cpp @@ -90,7 +90,9 @@ namespace Encodings { if (lang=="cho"){return "Choctaw";} if (lang=="chp"){return "Chipewyan; Dene Suline";} if (lang=="chr"){return "Cherokee";} - if (lang=="chu"){return "Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic";} + if (lang == "chu"){ + return "Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic"; + } if (lang=="chv"){return "Chuvash";} if (lang=="chy"){return "Cheyenne";} if (lang=="cmc"){return "Chamic languages";} @@ -514,7 +516,709 @@ namespace Encodings { return "Undetermined";// actually "und", assumed by default } + std::string ISO639::twoToThree(const std::string &lang){ + if (lang == "aa"){return "aar";} + if (lang == "ab"){return "abk";} + if (lang == "ae"){return "ave";} + if (lang == "af"){return "afr";} + if (lang == "ak"){return "aka";} + if (lang == "am"){return "amh";} + if (lang == "an"){return "arg";} + if (lang == "ar"){return "ara";} + if (lang == "as"){return "asm";} + if (lang == "av"){return "ava";} + if (lang == "ay"){return "aym";} + if (lang == "az"){return "aze";} + if (lang == "ba"){return "bak";} + if (lang == "be"){return "bel";} + if (lang == "bg"){return "bul";} + if (lang == "bh"){return "bih";} + if (lang == "bi"){return "bis";} + if (lang == "bm"){return "bam";} + if (lang == "bn"){return "ben";} + if (lang == "bo"){return "bod";} + if (lang == "br"){return "bre";} + if (lang == "bs"){return "bos";} + if (lang == "ca"){return "cat";} + if (lang == "ce"){return "che";} + if (lang == "ch"){return "cha";} + if (lang == "co"){return "cos";} + if (lang == "cr"){return "cre";} + if (lang == "cs"){return "ces";} + if (lang == "cu"){return "chu";} + if (lang == "cv"){return "chv";} + if (lang == "cy"){return "cym";} + if (lang == "da"){return "dan";} + if (lang == "de"){return "deu";} + if (lang == "dv"){return "div";} + if (lang == "dz"){return "dzo";} + if (lang == "ee"){return "ewe";} + if (lang == "el"){return "ell";} + if (lang == "en"){return "eng";} + if (lang == "eo"){return "epo";} + if (lang == "es"){return "spa";} + if (lang == "et"){return "est";} + if (lang == "eu"){return "eus";} + if (lang == "fa"){return "fas";} + if (lang == "ff"){return "ful";} + if (lang == "fi"){return "fin";} + if (lang == "fj"){return "fij";} + if (lang == "fo"){return "fao";} + if (lang == "fr"){return "fra";} + if (lang == "fy"){return "fry";} + if (lang == "ga"){return "gle";} + if (lang == "gd"){return "gla";} + if (lang == "gl"){return "glg";} + if (lang == "gn"){return "grn";} + if (lang == "gu"){return "guj";} + if (lang == "gv"){return "glv";} + if (lang == "ha"){return "hau";} + if (lang == "he"){return "heb";} + if (lang == "hi"){return "hin";} + if (lang == "ho"){return "hmo";} + if (lang == "hr"){return "hrv";} + if (lang == "ht"){return "hat";} + if (lang == "hu"){return "hun";} + if (lang == "hy"){return "hye";} + if (lang == "hz"){return "her";} + if (lang == "ia"){return "ina";} + if (lang == "id"){return "ind";} + if (lang == "ie"){return "ile";} + if (lang == "ig"){return "ibo";} + if (lang == "ii"){return "iii";} + if (lang == "ik"){return "ipk";} + if (lang == "io"){return "ido";} + if (lang == "is"){return "isl";} + if (lang == "it"){return "ita";} + if (lang == "iu"){return "iku";} + if (lang == "ja"){return "jpn";} + if (lang == "jv"){return "jav";} + if (lang == "ka"){return "kat";} + if (lang == "kg"){return "kon";} + if (lang == "ki"){return "kik";} + if (lang == "kj"){return "kua";} + if (lang == "kk"){return "kaz";} + if (lang == "kl"){return "kal";} + if (lang == "km"){return "khm";} + if (lang == "kn"){return "kan";} + if (lang == "ko"){return "kor";} + if (lang == "kr"){return "kau";} + if (lang == "ks"){return "kas";} + if (lang == "ku"){return "kur";} + if (lang == "kv"){return "kom";} + if (lang == "kw"){return "cor";} + if (lang == "ky"){return "kir";} + if (lang == "la"){return "lat";} + if (lang == "lb"){return "ltz";} + if (lang == "lg"){return "lug";} + if (lang == "li"){return "lim";} + if (lang == "ln"){return "lin";} + if (lang == "lo"){return "lao";} + if (lang == "lt"){return "lit";} + if (lang == "lu"){return "lub";} + if (lang == "lv"){return "lav";} + if (lang == "mg"){return "mlg";} + if (lang == "mh"){return "mah";} + if (lang == "mi"){return "mri";} + if (lang == "mk"){return "mkd";} + if (lang == "ml"){return "mal";} + if (lang == "mn"){return "mon";} + if (lang == "mr"){return "mar";} + if (lang == "ms"){return "msa";} + if (lang == "mt"){return "mlt";} + if (lang == "my"){return "mya";} + if (lang == "na"){return "nau";} + if (lang == "nb"){return "nob";} + if (lang == "nd"){return "nde";} + if (lang == "ne"){return "nep";} + if (lang == "ng"){return "ndo";} + if (lang == "nl"){return "nld";} + if (lang == "nn"){return "nno";} + if (lang == "no"){return "nor";} + if (lang == "nr"){return "nbl";} + if (lang == "nv"){return "nav";} + if (lang == "ny"){return "nya";} + if (lang == "oc"){return "oci";} + if (lang == "oj"){return "oji";} + if (lang == "om"){return "orm";} + if (lang == "or"){return "ori";} + if (lang == "os"){return "oss";} + if (lang == "pa"){return "pan";} + if (lang == "pi"){return "pli";} + if (lang == "pl"){return "pol";} + if (lang == "ps"){return "pus";} + if (lang == "pt"){return "por";} + if (lang == "qu"){return "que";} + if (lang == "rm"){return "roh";} + if (lang == "rn"){return "run";} + if (lang == "ro"){return "ron";} + if (lang == "ru"){return "rus";} + if (lang == "rw"){return "kin";} + if (lang == "sa"){return "san";} + if (lang == "sc"){return "srd";} + if (lang == "sd"){return "snd";} + if (lang == "se"){return "sme";} + if (lang == "sg"){return "sag";} + if (lang == "sh"){return "hbs";} + if (lang == "si"){return "sin";} + if (lang == "sk"){return "slk";} + if (lang == "sl"){return "slv";} + if (lang == "sm"){return "smo";} + if (lang == "sn"){return "sna";} + if (lang == "so"){return "som";} + if (lang == "sq"){return "sqi";} + if (lang == "sr"){return "srp";} + if (lang == "ss"){return "ssw";} + if (lang == "st"){return "sot";} + if (lang == "su"){return "sun";} + if (lang == "sv"){return "swe";} + if (lang == "sw"){return "swa";} + if (lang == "ta"){return "tam";} + if (lang == "te"){return "tel";} + if (lang == "tg"){return "tgk";} + if (lang == "th"){return "tha";} + if (lang == "ti"){return "tir";} + if (lang == "tk"){return "tuk";} + if (lang == "tl"){return "tgl";} + if (lang == "tn"){return "tsn";} + if (lang == "to"){return "ton";} + if (lang == "tr"){return "tur";} + if (lang == "ts"){return "tso";} + if (lang == "tt"){return "tat";} + if (lang == "tw"){return "twi";} + if (lang == "ty"){return "tah";} + if (lang == "ug"){return "uig";} + if (lang == "uk"){return "ukr";} + if (lang == "ur"){return "urd";} + if (lang == "uz"){return "uzb";} + if (lang == "ve"){return "ven";} + if (lang == "vi"){return "vie";} + if (lang == "vo"){return "vol";} + if (lang == "wa"){return "wln";} + if (lang == "wo"){return "wol";} + if (lang == "xh"){return "xho";} + if (lang == "yi"){return "yid";} + if (lang == "yo"){return "yor";} + if (lang == "za"){return "zha";} + if (lang == "zh"){return "zho";} + if (lang == "zu"){return "zul";} + return "und"; + } + std::string ISO639::encode(const std::string &lang){ + if (lang == "Afar"){return "aar";} + if (lang == "Abkhazian"){return "abk";} + if (lang == "Achinese"){return "ace";} + if (lang == "Acoli"){return "ach";} + if (lang == "Adangme"){return "ada";} + if (lang == "Adyghe; Adygei"){return "ady";} + if (lang == "Afro-Asiatic languages"){return "afa";} + if (lang == "Afrihili"){return "afh";} + if (lang == "Afrikaans"){return "afr";} + if (lang == "Ainu"){return "ain";} + if (lang == "Akan"){return "aka";} + if (lang == "Akkadian"){return "akk";} + if (lang == "Albanian"){return "alb";} + if (lang == "Aleut"){return "ale";} + if (lang == "Algonquian languages"){return "alg";} + if (lang == "Southern Altai"){return "alt";} + if (lang == "Amharic"){return "amh";} + if (lang == "English, Old (ca.450-1100)"){return "ang";} + if (lang == "Angika"){return "anp";} + if (lang == "Apache languages"){return "apa";} + if (lang == "Arabic"){return "ara";} + if (lang == "Official Aramaic (700-300 BCE); Imperial Aramaic (700-300 BCE)"){return "arc";} + if (lang == "Aragonese"){return "arg";} + if (lang == "Armenian"){return "arm";} + if (lang == "Mapudungun; Mapuche"){return "arn";} + if (lang == "Arapaho"){return "arp";} + if (lang == "Artificial languages"){return "art";} + if (lang == "Arawak"){return "arw";} + if (lang == "Assamese"){return "asm";} + if (lang == "Asturian; Bable; Leonese; Asturleonese"){return "ast";} + if (lang == "Athapascan languages"){return "ath";} + if (lang == "Australian languages"){return "aus";} + if (lang == "Avaric"){return "ava";} + if (lang == "Avestan"){return "ave";} + if (lang == "Awadhi"){return "awa";} + if (lang == "Aymara"){return "aym";} + if (lang == "Azerbaijani"){return "aze";} + if (lang == "Banda languages"){return "bad";} + if (lang == "Bamileke languages"){return "bai";} + if (lang == "Bashkir"){return "bak";} + if (lang == "Baluchi"){return "bal";} + if (lang == "Bambara"){return "bam";} + if (lang == "Balinese"){return "ban";} + if (lang == "Basque"){return "baq";} + if (lang == "Basa"){return "bas";} + if (lang == "Baltic languages"){return "bat";} + if (lang == "Beja; Bedawiyet"){return "bej";} + if (lang == "Belarusian"){return "bel";} + if (lang == "Bemba"){return "bem";} + if (lang == "Bengali"){return "ben";} + if (lang == "Berber languages"){return "ber";} + if (lang == "Bhojpuri"){return "bho";} + if (lang == "Bihari languages"){return "bih";} + if (lang == "Bikol"){return "bik";} + if (lang == "Bini; Edo"){return "bin";} + if (lang == "Bislama"){return "bis";} + if (lang == "Siksika"){return "bla";} + if (lang == "Bantu languages"){return "bnt";} + if (lang == "Tibetan"){return "bod";} + if (lang == "Bosnian"){return "bos";} + if (lang == "Braj"){return "bra";} + if (lang == "Breton"){return "bre";} + if (lang == "Batak languages"){return "btk";} + if (lang == "Buriat"){return "bua";} + if (lang == "Buginese"){return "bug";} + if (lang == "Bulgarian"){return "bul";} + if (lang == "Burmese"){return "bur";} + if (lang == "Blin; Bilin"){return "byn";} + if (lang == "Caddo"){return "cad";} + if (lang == "Central American Indian languages"){return "cai";} + if (lang == "Galibi Carib"){return "car";} + if (lang == "Catalan; Valencian"){return "cat";} + if (lang == "Caucasian languages"){return "cau";} + if (lang == "Cebuano"){return "ceb";} + if (lang == "Celtic languages"){return "cel";} + if (lang == "Czech"){return "ces";} + if (lang == "Chamorro"){return "cha";} + if (lang == "Chibcha"){return "chb";} + if (lang == "Chechen"){return "che";} + if (lang == "Chagatai"){return "chg";} + if (lang == "Chinese"){return "chi";} + if (lang == "Chuukese"){return "chk";} + if (lang == "Mari"){return "chm";} + if (lang == "Chinook jargon"){return "chn";} + if (lang == "Choctaw"){return "cho";} + if (lang == "Chipewyan; Dene Suline"){return "chp";} + if (lang == "Cherokee"){return "chr";} + if (lang == + "Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic"){ + return "chu"; + } + if (lang == "Chuvash"){return "chv";} + if (lang == "Cheyenne"){return "chy";} + if (lang == "Chamic languages"){return "cmc";} + if (lang == "Coptic"){return "cop";} + if (lang == "Cornish"){return "cor";} + if (lang == "Corsican"){return "cos";} + if (lang == "Creoles and pidgins, English based"){return "cpe";} + if (lang == "Creoles and pidgins, French-based"){return "cpf";} + if (lang == "Creoles and pidgins, Portuguese-based"){return "cpp";} + if (lang == "Cree"){return "cre";} + if (lang == "Crimean Tatar; Crimean Turkish"){return "crh";} + if (lang == "Creoles and pidgins"){return "crp";} + if (lang == "Kashubian"){return "csb";} + if (lang == "Cushitic languages"){return "cus";} + if (lang == "Welsh"){return "cym";} + if (lang == "Czech"){return "cze";} + if (lang == "Czech"){return "cze";} + if (lang == "Dakota"){return "dak";} + if (lang == "Danish"){return "dan";} + if (lang == "Dargwa"){return "dar";} + if (lang == "Land Dayak languages"){return "day";} + if (lang == "Delaware"){return "del";} + if (lang == "Slave (Athapascan)"){return "den";} + if (lang == "German"){return "deu";} + if (lang == "Dogrib"){return "dgr";} + if (lang == "Dinka"){return "din";} + if (lang == "Divehi; Dhivehi; Maldivian"){return "div";} + if (lang == "Dogri"){return "doi";} + if (lang == "Dravidian languages"){return "dra";} + if (lang == "Lower Sorbian"){return "dsb";} + if (lang == "Duala"){return "dua";} + if (lang == "Dutch, Middle (ca.1050-1350)"){return "dum";} + if (lang == "Dutch; Flemish"){return "dut";} + if (lang == "Dyula"){return "dyu";} + if (lang == "Dzongkha"){return "dzo";} + if (lang == "Efik"){return "efi";} + if (lang == "Egyptian (Ancient)"){return "egy";} + if (lang == "Ekajuk"){return "eka";} + if (lang == "Greek, Modern (1453-)"){return "ell";} + if (lang == "Elamite"){return "elx";} + if (lang == "English"){return "eng";} + if (lang == "English, Middle (1100-1500)"){return "enm";} + if (lang == "Esperanto"){return "epo";} + if (lang == "Estonian"){return "est";} + if (lang == "Basque"){return "eus";} + if (lang == "Basque"){return "eus";} + if (lang == "Ewe"){return "ewe";} + if (lang == "Ewondo"){return "ewo";} + if (lang == "Fang"){return "fan";} + if (lang == "Faroese"){return "fao";} + if (lang == "Persian"){return "fas";} + if (lang == "Persian"){return "fas";} + if (lang == "Fanti"){return "fat";} + if (lang == "Fijian"){return "fij";} + if (lang == "Filipino; Pilipino"){return "fil";} + if (lang == "Finnish"){return "fin";} + if (lang == "Finno-Ugrian languages"){return "fiu";} + if (lang == "Fon"){return "fon";} + if (lang == "French"){return "fra";} + if (lang == "French"){return "fre";} + if (lang == "French, Middle (ca.1400-1600)"){return "frm";} + if (lang == "French, Old (842-ca.1400)"){return "fro";} + if (lang == "Northern Frisian"){return "frr";} + if (lang == "Eastern Frisian"){return "frs";} + if (lang == "Western Frisian"){return "fry";} + if (lang == "Fulah"){return "ful";} + if (lang == "Friulian"){return "fur";} + if (lang == "Ga"){return "gaa";} + if (lang == "Gayo"){return "gay";} + if (lang == "Gbaya"){return "gba";} + if (lang == "Germanic languages"){return "gem";} + if (lang == "Georgian"){return "geo";} + if (lang == "German"){return "ger";} + if (lang == "Geez"){return "gez";} + if (lang == "Gilbertese"){return "gil";} + if (lang == "Gaelic; Scottish Gaelic"){return "gla";} + if (lang == "Irish"){return "gle";} + if (lang == "Galician"){return "glg";} + if (lang == "Manx"){return "glv";} + if (lang == "German, Middle High (ca.1050-1500)"){return "gmh";} + if (lang == "German, Old High (ca.750-1050)"){return "goh";} + if (lang == "Gondi"){return "gon";} + if (lang == "Gorontalo"){return "gor";} + if (lang == "Gothic"){return "got";} + if (lang == "Grebo"){return "grb";} + if (lang == "Greek, Ancient (to 1453)"){return "grc";} + if (lang == "Greek, Modern (1453-)"){return "gre";} + if (lang == "Guarani"){return "grn";} + if (lang == "Swiss German; Alemannic; Alsatian"){return "gsw";} + if (lang == "Gujarati"){return "guj";} + if (lang == "Gwich'in"){return "gwi";} + if (lang == "Haida"){return "hai";} + if (lang == "Haitian; Haitian Creole"){return "hat";} + if (lang == "Hausa"){return "hau";} + if (lang == "Hawaiian"){return "haw";} + if (lang == "Hebrew"){return "heb";} + if (lang == "Herero"){return "her";} + if (lang == "Hiligaynon"){return "hil";} + if (lang == "Himachali languages; Western Pahari languages"){return "him";} + if (lang == "Hindi"){return "hin";} + if (lang == "Hittite"){return "hit";} + if (lang == "Hmong; Mong"){return "hmn";} + if (lang == "Hiri Motu"){return "hmo";} + if (lang == "Croatian"){return "hrv";} + if (lang == "Upper Sorbian"){return "hsb";} + if (lang == "Hungarian"){return "hun";} + if (lang == "Hupa"){return "hup";} + if (lang == "Armenian"){return "hye";} + if (lang == "Iban"){return "iba";} + if (lang == "Igbo"){return "ibo";} + if (lang == "Icelandic"){return "ice";} + if (lang == "Ido"){return "ido";} + if (lang == "Sichuan Yi; Nuosu"){return "iii";} + if (lang == "Ijo languages"){return "ijo";} + if (lang == "Inuktitut"){return "iku";} + if (lang == "Interlingue; Occidental"){return "ile";} + if (lang == "Iloko"){return "ilo";} + if (lang == "Interlingua (International Auxiliary Language Association)"){return "ina";} + if (lang == "Indic languages"){return "inc";} + if (lang == "Indonesian"){return "ind";} + if (lang == "Indo-European languages"){return "ine";} + if (lang == "Ingush"){return "inh";} + if (lang == "Inupiaq"){return "ipk";} + if (lang == "Iranian languages"){return "ira";} + if (lang == "Iroquoian languages"){return "iro";} + if (lang == "Icelandic"){return "isl";} + if (lang == "Italian"){return "ita";} + if (lang == "Javanese"){return "jav";} + if (lang == "Lojban"){return "jbo";} + if (lang == "Japanese"){return "jpn";} + if (lang == "Judeo-Persian"){return "jpr";} + if (lang == "Judeo-Arabic"){return "jrb";} + if (lang == "Kara-Kalpak"){return "kaa";} + if (lang == "Kabyle"){return "kab";} + if (lang == "Kachin; Jingpho"){return "kac";} + if (lang == "Kalaallisut; Greenlandic"){return "kal";} + if (lang == "Kamba"){return "kam";} + if (lang == "Kannada"){return "kan";} + if (lang == "Karen languages"){return "kar";} + if (lang == "Kashmiri"){return "kas";} + if (lang == "Georgian"){return "kat";} + if (lang == "Kanuri"){return "kau";} + if (lang == "Kawi"){return "kaw";} + if (lang == "Kazakh"){return "kaz";} + if (lang == "Kabardian"){return "kbd";} + if (lang == "Khasi"){return "kha";} + if (lang == "Khoisan languages"){return "khi";} + if (lang == "Central Khmer"){return "khm";} + if (lang == "Khotanese; Sakan"){return "kho";} + if (lang == "Kikuyu; Gikuyu"){return "kik";} + if (lang == "Kinyarwanda"){return "kin";} + if (lang == "Kirghiz; Kyrgyz"){return "kir";} + if (lang == "Kimbundu"){return "kmb";} + if (lang == "Konkani"){return "kok";} + if (lang == "Komi"){return "kom";} + if (lang == "Kongo"){return "kon";} + if (lang == "Korean"){return "kor";} + if (lang == "Kosraean"){return "kos";} + if (lang == "Kpelle"){return "kpe";} + if (lang == "Karachay-Balkar"){return "krc";} + if (lang == "Karelian"){return "krl";} + if (lang == "Kru languages"){return "kro";} + if (lang == "Kurukh"){return "kru";} + if (lang == "Kuanyama; Kwanyama"){return "kua";} + if (lang == "Kumyk"){return "kum";} + if (lang == "Kurdish"){return "kur";} + if (lang == "Kutenai"){return "kut";} + if (lang == "Ladino"){return "lad";} + if (lang == "Lahnda"){return "lah";} + if (lang == "Lamba"){return "lam";} + if (lang == "Lao"){return "lao";} + if (lang == "Latin"){return "lat";} + if (lang == "Latvian"){return "lav";} + if (lang == "Lezghian"){return "lez";} + if (lang == "Limburgan; Limburger; Limburgish"){return "lim";} + if (lang == "Lingala"){return "lin";} + if (lang == "Lithuanian"){return "lit";} + if (lang == "Mongo"){return "lol";} + if (lang == "Lozi"){return "loz";} + if (lang == "Luxembourgish; Letzeburgesch"){return "ltz";} + if (lang == "Luba-Lulua"){return "lua";} + if (lang == "Luba-Katanga"){return "lub";} + if (lang == "Ganda"){return "lug";} + if (lang == "Luiseno"){return "lui";} + if (lang == "Lunda"){return "lun";} + if (lang == "Luo (Kenya and Tanzania)"){return "luo";} + if (lang == "Lushai"){return "lus";} + if (lang == "Macedonian"){return "mac";} + if (lang == "Madurese"){return "mad";} + if (lang == "Magahi"){return "mag";} + if (lang == "Marshallese"){return "mah";} + if (lang == "Maithili"){return "mai";} + if (lang == "Makasar"){return "mak";} + if (lang == "Malayalam"){return "mal";} + if (lang == "Mandingo"){return "man";} + if (lang == "Maori"){return "mao";} + if (lang == "Austronesian languages"){return "map";} + if (lang == "Marathi"){return "mar";} + if (lang == "Masai"){return "mas";} + if (lang == "Malay"){return "may";} + if (lang == "Moksha"){return "mdf";} + if (lang == "Mandar"){return "mdr";} + if (lang == "Mende"){return "men";} + if (lang == "Irish, Middle (900-1200)"){return "mga";} + if (lang == "Mi'kmaq; Micmac"){return "mic";} + if (lang == "Minangkabau"){return "min";} + if (lang == "Uncoded languages"){return "mis";} + if (lang == "Macedonian"){return "mkd";} + if (lang == "Mon-Khmer languages"){return "mkh";} + if (lang == "Malagasy"){return "mlg";} + if (lang == "Maltese"){return "mlt";} + if (lang == "Manchu"){return "mnc";} + if (lang == "Manipuri"){return "mni";} + if (lang == "Manobo languages"){return "mno";} + if (lang == "Mohawk"){return "moh";} + if (lang == "Mongolian"){return "mon";} + if (lang == "Mossi"){return "mos";} + if (lang == "Maori"){return "mri";} + if (lang == "Malay"){return "msa";} + if (lang == "Malay"){return "msa";} + if (lang == "Multiple languages"){return "mul";} + if (lang == "Munda languages"){return "mun";} + if (lang == "Creek"){return "mus";} + if (lang == "Mirandese"){return "mwl";} + if (lang == "Marwari"){return "mwr";} + if (lang == "Burmese"){return "mya";} + if (lang == "Mayan languages"){return "myn";} + if (lang == "Erzya"){return "myv";} + if (lang == "Nahuatl languages"){return "nah";} + if (lang == "North American Indian languages"){return "nai";} + if (lang == "Neapolitan"){return "nap";} + if (lang == "Nauru"){return "nau";} + if (lang == "Navajo; Navaho"){return "nav";} + if (lang == "Ndebele, South; South Ndebele"){return "nbl";} + if (lang == "Ndebele, North; North Ndebele"){return "nde";} + if (lang == "Ndonga"){return "ndo";} + if (lang == "Low German; Low Saxon; German, Low; Saxon, Low"){return "nds";} + if (lang == "Nepali"){return "nep";} + if (lang == "Nepal Bhasa; Newari"){return "new";} + if (lang == "Nias"){return "nia";} + if (lang == "Niger-Kordofanian languages"){return "nic";} + if (lang == "Niuean"){return "niu";} + if (lang == "Dutch; Flemish"){return "nld";} + if (lang == "Norwegian Nynorsk; Nynorsk, Norwegian"){return "nno";} + if (lang == "Bokmål, Norwegian; Norwegian Bokmål"){return "nob";} + if (lang == "Nogai"){return "nog";} + if (lang == "Norse, Old"){return "non";} + if (lang == "Norwegian"){return "nor";} + if (lang == "N'Ko"){return "nqo";} + if (lang == "Pedi; Sepedi; Northern Sotho"){return "nso";} + if (lang == "Nubian languages"){return "nub";} + if (lang == "Classical Newari; Old Newari; Classical Nepal Bhasa"){return "nwc";} + if (lang == "Chichewa; Chewa; Nyanja"){return "nya";} + if (lang == "Nyamwezi"){return "nym";} + if (lang == "Nyankole"){return "nyn";} + if (lang == "Nyoro"){return "nyo";} + if (lang == "Nzima"){return "nzi";} + if (lang == "Occitan (post 1500)"){return "oci";} + if (lang == "Ojibwa"){return "oji";} + if (lang == "Oriya"){return "ori";} + if (lang == "Oromo"){return "orm";} + if (lang == "Osage"){return "osa";} + if (lang == "Ossetian; Ossetic"){return "oss";} + if (lang == "Turkish, Ottoman (1500-1928)"){return "ota";} + if (lang == "Otomian languages"){return "oto";} + if (lang == "Papuan languages"){return "paa";} + if (lang == "Pangasinan"){return "pag";} + if (lang == "Pahlavi"){return "pal";} + if (lang == "Pampanga; Kapampangan"){return "pam";} + if (lang == "Panjabi; Punjabi"){return "pan";} + if (lang == "Papiamento"){return "pap";} + if (lang == "Palauan"){return "pau";} + if (lang == "Persian, Old (ca.600-400 B.C.)"){return "peo";} + if (lang == "Persian"){return "per";} + if (lang == "Philippine languages"){return "phi";} + if (lang == "Phoenician"){return "phn";} + if (lang == "Pali"){return "pli";} + if (lang == "Polish"){return "pol";} + if (lang == "Pohnpeian"){return "pon";} + if (lang == "Portuguese"){return "por";} + if (lang == "Prakrit languages"){return "pra";} + if (lang == "Provençal, Old (to 1500);Occitan, Old (to 1500)"){return "pro";} + if (lang == "Pushto; Pashto"){return "pus";} + if (lang == "Quechua"){return "que";} + if (lang == "Rajasthani"){return "raj";} + if (lang == "Rapanui"){return "rap";} + if (lang == "Rarotongan; Cook Islands Maori"){return "rar";} + if (lang == "Romance languages"){return "roa";} + if (lang == "Romansh"){return "roh";} + if (lang == "Romany"){return "rom";} + if (lang == "Romanian; Moldavian; Moldovan"){return "ron";} + if (lang == "Romanian; Moldavian; Moldovan"){return "rum";} + if (lang == "Rundi"){return "run";} + if (lang == "Aromanian; Arumanian; Macedo-Romanian"){return "rup";} + if (lang == "Russian"){return "rus";} + if (lang == "Sandawe"){return "sad";} + if (lang == "Sango"){return "sag";} + if (lang == "Yakut"){return "sah";} + if (lang == "South American Indian languages"){return "sai";} + if (lang == "Salishan languages"){return "sal";} + if (lang == "Samaritan Aramaic"){return "sam";} + if (lang == "Sanskrit"){return "san";} + if (lang == "Sasak"){return "sas";} + if (lang == "Santali"){return "sat";} + if (lang == "Sicilian"){return "scn";} + if (lang == "Scots"){return "sco";} + if (lang == "Selkup"){return "sel";} + if (lang == "Semitic languages"){return "sem";} + if (lang == "Irish, Old (to 900)"){return "sga";} + if (lang == "Sign Languages"){return "sgn";} + if (lang == "Shan"){return "shn";} + if (lang == "Sidamo"){return "sid";} + if (lang == "Sinhala; Sinhalese"){return "sin";} + if (lang == "Siouan languages"){return "sio";} + if (lang == "Sino-Tibetan languages"){return "sit";} + if (lang == "Slavic languages"){return "sla";} + if (lang == "Slovak"){return "slk";} + if (lang == "Slovak"){return "slo";} + if (lang == "Slovenian"){return "slv";} + if (lang == "Southern Sami"){return "sma";} + if (lang == "Northern Sami"){return "sme";} + if (lang == "Sami languages"){return "smi";} + if (lang == "Lule Sami"){return "smj";} + if (lang == "Inari Sami"){return "smn";} + if (lang == "Samoan"){return "smo";} + if (lang == "Skolt Sami"){return "sms";} + if (lang == "Shona"){return "sna";} + if (lang == "Sindhi"){return "snd";} + if (lang == "Soninke"){return "snk";} + if (lang == "Sogdian"){return "sog";} + if (lang == "Somali"){return "som";} + if (lang == "Songhai languages"){return "son";} + if (lang == "Sotho, Southern"){return "sot";} + if (lang == "Spanish; Castilian"){return "spa";} + if (lang == "Albanian"){return "sqi";} + if (lang == "Sardinian"){return "srd";} + if (lang == "Sranan Tongo"){return "srn";} + if (lang == "Serbian"){return "srp";} + if (lang == "Serer"){return "srr";} + if (lang == "Nilo-Saharan languages"){return "ssa";} + if (lang == "Swati"){return "ssw";} + if (lang == "Sukuma"){return "suk";} + if (lang == "Sundanese"){return "sun";} + if (lang == "Susu"){return "sus";} + if (lang == "Sumerian"){return "sux";} + if (lang == "Swahili"){return "swa";} + if (lang == "Swedish"){return "swe";} + if (lang == "Classical Syriac"){return "syc";} + if (lang == "Syriac"){return "syr";} + if (lang == "Tahitian"){return "tah";} + if (lang == "Tai languages"){return "tai";} + if (lang == "Tamil"){return "tam";} + if (lang == "Tatar"){return "tat";} + if (lang == "Telugu"){return "tel";} + if (lang == "Timne"){return "tem";} + if (lang == "Tereno"){return "ter";} + if (lang == "Tetum"){return "tet";} + if (lang == "Tajik"){return "tgk";} + if (lang == "Tagalog"){return "tgl";} + if (lang == "Thai"){return "tha";} + if (lang == "Tibetan"){return "tib";} + if (lang == "Tigre"){return "tig";} + if (lang == "Tigrinya"){return "tir";} + if (lang == "Tiv"){return "tiv";} + if (lang == "Tokelau"){return "tkl";} + if (lang == "Klingon; tlhIngan-Hol"){return "tlh";} + if (lang == "Tlingit"){return "tli";} + if (lang == "Tamashek"){return "tmh";} + if (lang == "Tonga (Nyasa)"){return "tog";} + if (lang == "Tonga (Tonga Islands)"){return "ton";} + if (lang == "Tok Pisin"){return "tpi";} + if (lang == "Tsimshian"){return "tsi";} + if (lang == "Tswana"){return "tsn";} + if (lang == "Tsonga"){return "tso";} + if (lang == "Turkmen"){return "tuk";} + if (lang == "Tumbuka"){return "tum";} + if (lang == "Tupi languages"){return "tup";} + if (lang == "Turkish"){return "tur";} + if (lang == "Altaic languages"){return "tut";} + if (lang == "Tuvalu"){return "tvl";} + if (lang == "Twi"){return "twi";} + if (lang == "Tuvinian"){return "tyv";} + if (lang == "Udmurt"){return "udm";} + if (lang == "Ugaritic"){return "uga";} + if (lang == "Uighur; Uyghur"){return "uig";} + if (lang == "Ukrainian"){return "ukr";} + if (lang == "Umbundu"){return "umb";} + if (lang == "Urdu"){return "urd";} + if (lang == "Uzbek"){return "uzb";} + if (lang == "Vai"){return "vai";} + if (lang == "Venda"){return "ven";} + if (lang == "Vietnamese"){return "vie";} + if (lang == "Volapük"){return "vol";} + if (lang == "Votic"){return "vot";} + if (lang == "Wakashan languages"){return "wak";} + if (lang == "Wolaitta; Wolaytta"){return "wal";} + if (lang == "Waray"){return "war";} + if (lang == "Washo"){return "was";} + if (lang == "Welsh"){return "wel";} + if (lang == "Sorbian languages"){return "wen";} + if (lang == "Walloon"){return "wln";} + if (lang == "Wolof"){return "wol";} + if (lang == "Kalmyk; Oirat"){return "xal";} + if (lang == "Xhosa"){return "xho";} + if (lang == "Yao"){return "yao";} + if (lang == "Yapese"){return "yap";} + if (lang == "Yiddish"){return "yid";} + if (lang == "Yoruba"){return "yor";} + if (lang == "Yupik languages"){return "ypk";} + if (lang == "Zapotec"){return "zap";} + if (lang == "Blissymbols; Blissymbolics; Bliss"){return "zbl";} + if (lang == "Zenaga"){return "zen";} + if (lang == "Standard Moroccan Tamazight"){return "zgh";} + if (lang == "Zhuang; Chuang"){return "zha";} + if (lang == "Chinese"){return "zho";} + if (lang == "Zande languages"){return "znd";} + if (lang == "Zulu"){return "zul";} + if (lang == "Zuni"){return "zun";} + if (lang == "No linguistic content; Not applicable"){return "zxx";} + if (lang == "Zaza; Dimili; Dimli; Kirdki; Kirmanjki; Zazaki"){return "zza";} + return "und"; + } -} +}// namespace Encodings diff --git a/lib/langcodes.h b/lib/langcodes.h index c2c5f7d3..b767b14b 100644 --- a/lib/langcodes.h +++ b/lib/langcodes.h @@ -5,6 +5,8 @@ namespace Encodings { class ISO639{ public: static std::string decode(const std::string & lang); + static std::string twoToThree(const std::string & lang); + static std::string encode(const std::string & lang); }; diff --git a/src/output/output.cpp b/src/output/output.cpp index f82b915f..52c7b1f9 100644 --- a/src/output/output.cpp +++ b/src/output/output.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include "output.h" namespace Mist{ @@ -267,6 +268,63 @@ namespace Mist{ } } + /// Selects a specific track or set of tracks of the given trackType, using trackVal to decide. + /// trackVal may be a comma-separated list of numbers, codecs or the word "all"/"none" or an asterisk. + /// Does not do any checks if the protocol supports these tracks, just selects blindly. + void Output::selectTrack(const std::string &trackType, const std::string &trackVal){ + if (!trackVal.size() || trackVal == "0" || trackVal == "none"){return;}//don't select anything in particular + if (trackVal.find(',') != std::string::npos){ + //Comma-separated list, recurse. + std::stringstream ss(trackVal); + std::string item; + while (std::getline(ss, item, ',')){selectTrack(trackType, item);} + return; + } + uint64_t trackNo = JSON::Value(trackVal).asInt(); + if (trackVal == JSON::Value(trackNo).asString()){ + //It's an integer number + if (!myMeta.tracks.count(trackNo)){ + INFO_MSG("Track %lld does not exist in stream, cannot select", trackNo); + return; + } + const DTSC::Track & Trk = myMeta.tracks[trackNo]; + if (Trk.type != trackType && Trk.codec != trackType){ + INFO_MSG("Track %lld is not %s (%s/%s), cannot select", trackNo, trackType.c_str(), Trk.type.c_str(), Trk.codec.c_str()); + return; + } + INFO_MSG("Selecting %s track %lld (%s/%s)", trackType.c_str(), trackNo, Trk.type.c_str(), Trk.codec.c_str()); + selectedTracks.insert(trackNo); + return; + } + std::string trackLow = trackVal; + Util::stringToLower(trackLow); + if (trackLow == "all" || trackLow == "*"){ + //select all tracks of this type + for (std::map::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++){ + const DTSC::Track & Trk = it->second; + if (Trk.type == trackType || Trk.codec == trackType){ + selectedTracks.insert(it->first); + INFO_MSG("Selecting %s track %lu (%s/%s)", trackType.c_str(), it->first, Trk.type.c_str(), Trk.codec.c_str()); + } + } + return; + } + //attempt to do language/codec matching + //convert 2-character language codes into 3-character language codes + if (trackLow.size() == 2){trackLow = Encodings::ISO639::twoToThree(trackLow);} + for (std::map::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++){ + const DTSC::Track & Trk = it->second; + if (Trk.type == trackType || Trk.codec == trackType){ + std::string codecLow = Trk.codec; + Util::stringToLower(codecLow); + if (Trk.lang == trackLow || trackLow == codecLow){ + selectedTracks.insert(it->first); + INFO_MSG("Selecting %s track %lu (%s/%s)", trackType.c_str(), it->first, Trk.type.c_str(), Trk.codec.c_str()); + } + } + } + } + /// Automatically selects the tracks that are possible and/or wanted. /// Returns true if the track selection changed in any way. bool Output::selectDefaultTracks(){ @@ -282,6 +340,21 @@ namespace Mist{ bool autoSeek = buffer.size(); uint64_t seekTarget = currentTime(); + bool noSelAudio = false, noSelVideo = false, noSelSub = false; + //Then, select the tracks we've been asked to select. + if (targetParams.count("audio") && targetParams["audio"].size()){ + selectTrack("audio", targetParams["audio"]); + noSelAudio = true; + } + if (targetParams.count("video") && targetParams["video"].size()){ + selectTrack("video", targetParams["video"]); + noSelVideo = true; + } + if (targetParams.count("subtitle") && targetParams["subtitle"].size()){ + selectTrack("subtitle", targetParams["subtitle"]); + noSelSub = true; + } + //check which tracks don't actually exist std::set toRemove; for (std::set::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){ @@ -383,6 +456,9 @@ namespace Mist{ for (std::map::reverse_iterator trit = myMeta.tracks.rbegin(); trit != myMeta.tracks.rend(); trit++){ if ((!byType && trit->second.codec == strRef.substr(shift)) || (byType && trit->second.type == strRef.substr(shift)) || strRef.substr(shift) == "*"){ if (autoSeek && trit->second.lastms < std::max(seekTarget, (uint64_t)6000lu) - 6000){continue;} + if (noSelAudio && trit->second.type == "audio"){continue;} + if (noSelVideo && trit->second.type == "video"){continue;} + if (noSelSub && (trit->second.type == "subtitle" || trit->second.codec == "subtitle")){continue;} //user-agent-check bool problems = false; if (capa.isMember("exceptions") && capa["exceptions"].isObject() && capa["exceptions"].size()){ @@ -403,6 +479,9 @@ namespace Mist{ for (std::map::iterator trit = myMeta.tracks.begin(); trit != myMeta.tracks.end(); trit++){ if ((!byType && trit->second.codec == strRef.substr(shift)) || (byType && trit->second.type == strRef.substr(shift)) || strRef.substr(shift) == "*"){ if (autoSeek && trit->second.lastms < std::max(seekTarget, (uint64_t)6000lu) - 6000){continue;} + if (noSelAudio && trit->second.type == "audio"){continue;} + if (noSelVideo && trit->second.type == "video"){continue;} + if (noSelSub && (trit->second.type == "subtitle" || trit->second.codec == "subtitle")){continue;} //user-agent-check bool problems = false; if (capa.isMember("exceptions") && capa["exceptions"].isObject() && capa["exceptions"].size()){ diff --git a/src/output/output.h b/src/output/output.h index cfe5def3..3b5ae09b 100644 --- a/src/output/output.h +++ b/src/output/output.h @@ -52,6 +52,7 @@ namespace Mist { uint64_t liveTime(); void setBlocking(bool blocking); void updateMeta(); + void selectTrack(const std::string &trackType, const std::string &trackVal); bool selectDefaultTracks(); bool connectToFile(std::string file); static bool listenMode(){return true;} @@ -88,6 +89,7 @@ namespace Mist { bool sought;/// targetParams; std::string UA; ///< User Agent string, if known. uint16_t uaDelay;///