Compare commits

...

4 Commits
tested ... main

Author SHA1 Message Date
TylerCG
92c385525a strip audio 2026-01-10 12:53:01 -05:00
TylerCG
9b47d95605 tweaks 2026-01-08 18:52:06 -05:00
TylerCG
f7e4e1766b EAC3 Compatibility 2026-01-01 18:22:19 -05:00
TylerCG
7323029edb readme 2026-01-01 15:48:31 -05:00
28 changed files with 10492 additions and 502 deletions

View File

@ -16,7 +16,7 @@
"P:\\movies\\The Trial of the Chicago 7 (2020)": 904710368, "P:\\movies\\The Trial of the Chicago 7 (2020)": 904710368,
"P:\\movies\\Breaking (2022)": 995048915, "P:\\movies\\Breaking (2022)": 995048915,
"P:\\movies\\Zack Snyder's Justice League (2021)": 6428185686, "P:\\movies\\Zack Snyder's Justice League (2021)": 6428185686,
"P:\\movies\\Premium Rush (2012)": 4184150405, "P:\\movies\\Premium Rush (2012)": 2174933523,
"P:\\movies\\Daddy's Home (2015)": 734920111, "P:\\movies\\Daddy's Home (2015)": 734920111,
"P:\\movies\\Concussion (2015)": 954083779, "P:\\movies\\Concussion (2015)": 954083779,
"P:\\movies\\Lisa Frankenstein (2024)": 975415847, "P:\\movies\\Lisa Frankenstein (2024)": 975415847,
@ -48,6 +48,7 @@
"P:\\movies\\Despicable Me 3 (2017)": 690230066, "P:\\movies\\Despicable Me 3 (2017)": 690230066,
"P:\\movies\\Rush (2013)": 913581666, "P:\\movies\\Rush (2013)": 913581666,
"P:\\movies\\The Nun II (2023)": 1057333481, "P:\\movies\\The Nun II (2023)": 1057333481,
"P:\\movies\\The Amityville Horror (2005)": 629562643,
"P:\\movies\\SAW II (2005)": 628644928, "P:\\movies\\SAW II (2005)": 628644928,
"P:\\movies\\Fortress (2021)": 950706654, "P:\\movies\\Fortress (2021)": 950706654,
"P:\\movies\\Cocaine Bear (2023)": 923105028, "P:\\movies\\Cocaine Bear (2023)": 923105028,
@ -139,9 +140,10 @@
"P:\\movies\\Harold and Kumar - Go To White Castle (2004)": 578054843, "P:\\movies\\Harold and Kumar - Go To White Castle (2004)": 578054843,
"P:\\movies\\Pok\u00e9mon - Destiny Deoxys (2004)": 4139612884, "P:\\movies\\Pok\u00e9mon - Destiny Deoxys (2004)": 4139612884,
"P:\\movies\\We Live in Time (2024)": 1148398986, "P:\\movies\\We Live in Time (2024)": 1148398986,
"P:\\movies\\The Suicide Squad (2021)": 5220542826, "P:\\movies\\The Suicide Squad (2021)": 3193385912,
"P:\\movies\\What We Do in the Shadows (2014)": 1324961025, "P:\\movies\\What We Do in the Shadows (2014)": 1324961025,
"P:\\movies\\Pok\u00e9mon the Movie - Secrets of the Jungle (2020)": 2970730073, "P:\\movies\\Pok\u00e9mon the Movie - Secrets of the Jungle (2020)": 2970730073,
"P:\\movies\\Predators (2010)": 575097100,
"P:\\movies\\First Shift (2024)": 862392953, "P:\\movies\\First Shift (2024)": 862392953,
"P:\\movies\\Christmas with the Campbells (2022)": 848536671, "P:\\movies\\Christmas with the Campbells (2022)": 848536671,
"P:\\movies\\Chicken Run - Dawn of the Nugget (2023)": 980150751, "P:\\movies\\Chicken Run - Dawn of the Nugget (2023)": 980150751,
@ -314,7 +316,7 @@
"P:\\movies\\Cats & Dogs - The Revenge of Kitty Galore (2010)": 794156004, "P:\\movies\\Cats & Dogs - The Revenge of Kitty Galore (2010)": 794156004,
"P:\\movies\\Instant Family (2018)": 1039796631, "P:\\movies\\Instant Family (2018)": 1039796631,
"P:\\movies\\Predator - Killer of Killers (2025)": 816946827, "P:\\movies\\Predator - Killer of Killers (2025)": 816946827,
"P:\\movies\\Little Fockers (2010)": 523155307, "P:\\movies\\Little Fockers (2010)": 934347829,
"P:\\movies\\22 Jump Street (2014)": 856601465, "P:\\movies\\22 Jump Street (2014)": 856601465,
"P:\\movies\\Bambi (1942)": 577460194, "P:\\movies\\Bambi (1942)": 577460194,
"P:\\movies\\Sleeping Beauty (1959)": 1258101653, "P:\\movies\\Sleeping Beauty (1959)": 1258101653,
@ -447,7 +449,7 @@
"P:\\movies\\The Theory of Everything (2014)": 1014618750, "P:\\movies\\The Theory of Everything (2014)": 1014618750,
"P:\\movies\\Hotel for the Holidays (2022)": 813498323, "P:\\movies\\Hotel for the Holidays (2022)": 813498323,
"P:\\movies\\Tomorrowland (2015)": 914578217, "P:\\movies\\Tomorrowland (2015)": 914578217,
"P:\\movies\\Scott Pilgrim vs. the World (2010)": 5104233824, "P:\\movies\\Scott Pilgrim vs. the World (2010)": 2890731039,
"P:\\movies\\Reign of the Supermen (2019)": 786280131, "P:\\movies\\Reign of the Supermen (2019)": 786280131,
"P:\\movies\\The Bricklayer (2023)": 1060158754, "P:\\movies\\The Bricklayer (2023)": 1060158754,
"P:\\movies\\Sinners (2025)": 2230413475, "P:\\movies\\Sinners (2025)": 2230413475,
@ -527,6 +529,7 @@
"P:\\movies\\Bill and Ted's Bogus Journey (1991)": 1873085140, "P:\\movies\\Bill and Ted's Bogus Journey (1991)": 1873085140,
"P:\\movies\\Honey Don't! (2025)": 861699209, "P:\\movies\\Honey Don't! (2025)": 861699209,
"P:\\movies\\Honey, I Blew Up the Kid (1992)": 788453313, "P:\\movies\\Honey, I Blew Up the Kid (1992)": 788453313,
"P:\\movies\\AJR - Somewhere in the sky (2026)": 15484584956,
"P:\\movies\\Cyrano (2021)": 1186014065, "P:\\movies\\Cyrano (2021)": 1186014065,
"P:\\movies\\The Dark Tower (2017)": 960436348, "P:\\movies\\The Dark Tower (2017)": 960436348,
"P:\\movies\\Good Boy! (2003)": 844713316, "P:\\movies\\Good Boy! (2003)": 844713316,
@ -613,17 +616,19 @@
"P:\\movies\\Safe House (2012)": 787215510, "P:\\movies\\Safe House (2012)": 787215510,
"P:\\movies\\Pok\u00e9mon Detective Pikachu (2019)": 2033856759, "P:\\movies\\Pok\u00e9mon Detective Pikachu (2019)": 2033856759,
"P:\\movies\\Superman - Red Son (2020)": 811801544, "P:\\movies\\Superman - Red Son (2020)": 811801544,
"P:\\movies\\Pirates of the Caribbean - Dead Man's Chest (2006)": 3785474444, "P:\\movies\\High Rollers (2025)": 976326920,
"P:\\movies\\Pirates of the Caribbean - Dead Man's Chest (2006)": 5677959143,
"P:\\movies\\Waitress (2007)": 1008081415, "P:\\movies\\Waitress (2007)": 1008081415,
"P:\\movies\\Chef (2014)": 854812021, "P:\\movies\\Chef (2014)": 854812021,
"P:\\movies\\Spider-Man (2002)": 1979695887, "P:\\movies\\Spider-Man (2002)": 1979695887,
"P:\\movies\\Five Nights at Freddy's 2 (2025)": 1003470675,
"P:\\movies\\Patch Adams (1998)": 1017725633, "P:\\movies\\Patch Adams (1998)": 1017725633,
"P:\\movies\\The Conjuring - Last Rites (2025)": 1307715145, "P:\\movies\\The Conjuring - Last Rites (2025)": 1307715145,
"P:\\movies\\Theater Camp (2023)": 891947338, "P:\\movies\\Theater Camp (2023)": 891947338,
"P:\\movies\\Turning Red (2022)": 962622557, "P:\\movies\\Turning Red (2022)": 962622557,
"P:\\movies\\Dungeons & Dragons - Honor Among Thieves (2023)": 2656730936, "P:\\movies\\Dungeons & Dragons - Honor Among Thieves (2023)": 2656730936,
"P:\\movies\\Paycheck (2003)": 993810724, "P:\\movies\\Paycheck (2003)": 993810724,
"P:\\movies\\Wolf Children (2012)": 4453912541, "P:\\movies\\Wolf Children (2012)": 1929928928,
"P:\\movies\\Uproar (2023)": 1061433898, "P:\\movies\\Uproar (2023)": 1061433898,
"P:\\movies\\Coup! (2024)": 900305483, "P:\\movies\\Coup! (2024)": 900305483,
"P:\\movies\\Old (2021)": 1043284170, "P:\\movies\\Old (2021)": 1043284170,
@ -653,7 +658,7 @@
"P:\\movies\\Transporter 3 (2008)": 629053239, "P:\\movies\\Transporter 3 (2008)": 629053239,
"P:\\movies\\Red Rocket (2021)": 1250775533, "P:\\movies\\Red Rocket (2021)": 1250775533,
"P:\\movies\\Chaos (2005)": 848357261, "P:\\movies\\Chaos (2005)": 848357261,
"P:\\movies\\Superman (2025)": 13124179581, "P:\\movies\\Superman (2025)": 7519012512,
"P:\\movies\\Layer Cake (2004)": 682551661, "P:\\movies\\Layer Cake (2004)": 682551661,
"P:\\movies\\Once Upon a Christmas Miracle (2018)": 819838950, "P:\\movies\\Once Upon a Christmas Miracle (2018)": 819838950,
"P:\\movies\\You Hurt My Feelings (2023)": 895680655, "P:\\movies\\You Hurt My Feelings (2023)": 895680655,
@ -665,7 +670,7 @@
"P:\\movies\\Badland Hunters (2024)": 1049775793, "P:\\movies\\Badland Hunters (2024)": 1049775793,
"P:\\movies\\Gangster No. 1 (2000)": 990977285, "P:\\movies\\Gangster No. 1 (2000)": 990977285,
"P:\\movies\\Am I Racist! (2024)": 837441227, "P:\\movies\\Am I Racist! (2024)": 837441227,
"P:\\movies\\Ferris Bueller's Day Off (1986)": 5980268040, "P:\\movies\\Ferris Bueller's Day Off (1986)": 3533513139,
"P:\\movies\\Margin Call (2011)": 734058146, "P:\\movies\\Margin Call (2011)": 734058146,
"P:\\movies\\When You Finish Saving the World (2023)": 844223076, "P:\\movies\\When You Finish Saving the World (2023)": 844223076,
"P:\\movies\\The Nines (2007)": 894876710, "P:\\movies\\The Nines (2007)": 894876710,
@ -946,14 +951,14 @@
"P:\\movies\\Ponyo (2008)": 5677514449, "P:\\movies\\Ponyo (2008)": 5677514449,
"P:\\movies\\BASEketball (1998)": 994729312, "P:\\movies\\BASEketball (1998)": 994729312,
"P:\\movies\\Hunter x Hunter - Phantom Rouge (2013)": 864950409, "P:\\movies\\Hunter x Hunter - Phantom Rouge (2013)": 864950409,
"P:\\movies\\Pirates of the Caribbean - At World's End (2007)": 4117617111, "P:\\movies\\Pirates of the Caribbean - At World's End (2007)": 6961369007,
"P:\\movies\\Detective Knight - Rogue (2022)": 1012614253, "P:\\movies\\Detective Knight - Rogue (2022)": 1012614253,
"P:\\movies\\Cliffhanger (1993)": 786895598, "P:\\movies\\Cliffhanger (1993)": 786895598,
"P:\\movies\\Slap Shot (1977)": 910196582, "P:\\movies\\Slap Shot (1977)": 910196582,
"P:\\movies\\Jackass 3.5 (2011)": 785709162, "P:\\movies\\Jackass 3.5 (2011)": 785709162,
"P:\\movies\\Ocean's Eight (2018)": 983734563, "P:\\movies\\Ocean's Eight (2018)": 983734563,
"P:\\movies\\Maze Runner - The Death Cure (2018)": 1305954358, "P:\\movies\\Maze Runner - The Death Cure (2018)": 1305954358,
"P:\\movies\\Venom - The Last Dance (2024)": 5722931819, "P:\\movies\\Venom - The Last Dance (2024)": 1798147779,
"P:\\movies\\Tron (1982)": 727876107, "P:\\movies\\Tron (1982)": 727876107,
"P:\\movies\\Sonic the Hedgehog 2 (2022)": 2043660783, "P:\\movies\\Sonic the Hedgehog 2 (2022)": 2043660783,
"P:\\movies\\Sherlock Holmes - A Game of Shadows (2011)": 841467769, "P:\\movies\\Sherlock Holmes - A Game of Shadows (2011)": 841467769,
@ -1003,9 +1008,11 @@
"P:\\movies\\Waterworld (1995)": 1069371604, "P:\\movies\\Waterworld (1995)": 1069371604,
"P:\\movies\\Longlegs (2024)": 835974578, "P:\\movies\\Longlegs (2024)": 835974578,
"P:\\movies\\Dual (2022)": 909646357, "P:\\movies\\Dual (2022)": 909646357,
"P:\\movies\\xXx - Return of Xander Cage (2017)": 9537340240, "P:\\movies\\xXx - Return of Xander Cage (2017)": 3563512464,
"P:\\movies\\Robin Williams - Come Inside My Mind (2018)": 1021217913,
"P:\\movies\\Brave (2012)": 629765937, "P:\\movies\\Brave (2012)": 629765937,
"P:\\movies\\Batman and Harley Quinn (2017)": 575516986, "P:\\movies\\Batman and Harley Quinn (2017)": 575516986,
"P:\\movies\\Hunting Season (2025)": 966911333,
"P:\\movies\\Last Flag Flying (2017)": 947531807, "P:\\movies\\Last Flag Flying (2017)": 947531807,
"P:\\movies\\A Long Way Down (2014)": 792782735, "P:\\movies\\A Long Way Down (2014)": 792782735,
"P:\\movies\\Shin Godzilla (2016)": 1951714489, "P:\\movies\\Shin Godzilla (2016)": 1951714489,
@ -1051,7 +1058,7 @@
"P:\\movies\\Santa's Slay (2005)": 1677244892, "P:\\movies\\Santa's Slay (2005)": 1677244892,
"P:\\movies\\Nate Bargatze - Full Time Magic (2015)": 604267174, "P:\\movies\\Nate Bargatze - Full Time Magic (2015)": 604267174,
"P:\\movies\\MK Ultra (2022)": 937505528, "P:\\movies\\MK Ultra (2022)": 937505528,
"P:\\movies\\Captain America - Brave New World (2025)": 5999464570, "P:\\movies\\Captain America - Brave New World (2025)": 2240251682,
"P:\\movies\\Mad Max 2 (1981)": 1504425460, "P:\\movies\\Mad Max 2 (1981)": 1504425460,
"P:\\movies\\Apocalypse Now (1979)": 1771332102, "P:\\movies\\Apocalypse Now (1979)": 1771332102,
"P:\\movies\\Rambo - Last Blood (2019)": 1025949915, "P:\\movies\\Rambo - Last Blood (2019)": 1025949915,
@ -1131,7 +1138,7 @@
"P:\\movies\\Ghostbusters (1984)": 1756467527, "P:\\movies\\Ghostbusters (1984)": 1756467527,
"P:\\movies\\This Means War (2012)": 734559917, "P:\\movies\\This Means War (2012)": 734559917,
"P:\\movies\\Reunion (2024)": 909882084, "P:\\movies\\Reunion (2024)": 909882084,
"P:\\movies\\The Losers (2010)": 5151113302, "P:\\movies\\The Losers (2010)": 2964760220,
"P:\\movies\\Fighting with My Family (2019)": 964548802, "P:\\movies\\Fighting with My Family (2019)": 964548802,
"P:\\movies\\Strays (2023)": 910698288, "P:\\movies\\Strays (2023)": 910698288,
"P:\\movies\\Hansan - Rising Dragon (2022)": 1253568599, "P:\\movies\\Hansan - Rising Dragon (2022)": 1253568599,
@ -1235,19 +1242,19 @@
"P:\\movies\\A Fantastic Fear of Everything (2012)": 786055829, "P:\\movies\\A Fantastic Fear of Everything (2012)": 786055829,
"P:\\movies\\Green Room (2015)": 737645792, "P:\\movies\\Green Room (2015)": 737645792,
"P:\\movies\\Rise of the Guardians (2012)": 733537206, "P:\\movies\\Rise of the Guardians (2012)": 733537206,
"P:\\movies\\The Roundup (2022)": 5716789610, "P:\\movies\\The Roundup (2022)": 2397207186,
"P:\\movies\\The Great Wall (2016)": 794233234, "P:\\movies\\The Great Wall (2016)": 794233234,
"P:\\movies\\Green Day - 20 Years of American Idiot (2024)": 1064467825, "P:\\movies\\Green Day - 20 Years of American Idiot (2024)": 1064467825,
"P:\\movies\\Sorry to Bother You (2018)": 981546629, "P:\\movies\\Sorry to Bother You (2018)": 981546629,
"P:\\movies\\Merry In-Laws (2012)": 849094480, "P:\\movies\\Merry In-Laws (2012)": 849094480,
"P:\\movies\\Black Clover - Sword of the Wizard King (2023)": 2792853722, "P:\\movies\\Black Clover - Sword of the Wizard King (2023)": 2792853722,
"P:\\movies\\Rocky V (1990)": 683775581, "P:\\movies\\Rocky V (1990)": 683775581,
"P:\\movies\\Starship Troopers (1997)": 7366521230, "P:\\movies\\Starship Troopers (1997)": 5339159761,
"P:\\movies\\Megamind (2010)": 629041367, "P:\\movies\\Megamind (2010)": 629041367,
"P:\\movies\\Mad God (2021)": 809156360, "P:\\movies\\Mad God (2021)": 809156360,
"P:\\movies\\The Other Zoey (2023)": 885187485, "P:\\movies\\The Other Zoey (2023)": 885187485,
"P:\\movies\\The Hunt (2020)": 866933622, "P:\\movies\\The Hunt (2020)": 866933622,
"P:\\movies\\Pirates of the Caribbean - Dead Men Tell No Tales (2017)": 3171926078, "P:\\movies\\Pirates of the Caribbean - Dead Men Tell No Tales (2017)": 3600745878,
"P:\\movies\\Spanglish (2004)": 996868451, "P:\\movies\\Spanglish (2004)": 996868451,
"P:\\movies\\Holes (2003)": 1674984992, "P:\\movies\\Holes (2003)": 1674984992,
"P:\\movies\\Big Trouble (2002)": 762439934, "P:\\movies\\Big Trouble (2002)": 762439934,
@ -1295,7 +1302,7 @@
"P:\\movies\\Confess, Fletch (2022)": 948327659, "P:\\movies\\Confess, Fletch (2022)": 948327659,
"P:\\movies\\Nine Days (2021)": 1192058593, "P:\\movies\\Nine Days (2021)": 1192058593,
"P:\\movies\\Me and Earl and the Dying Girl (2015)": 2588837590, "P:\\movies\\Me and Earl and the Dying Girl (2015)": 2588837590,
"P:\\movies\\The Intern (2015)": 5020752182, "P:\\movies\\The Intern (2015)": 2681947283,
"P:\\movies\\The Bounty Hunter (2010)": 840237747, "P:\\movies\\The Bounty Hunter (2010)": 840237747,
"P:\\movies\\One Hour Photo (2002)": 926656817, "P:\\movies\\One Hour Photo (2002)": 926656817,
"P:\\movies\\Life After People (2008)": 856319577, "P:\\movies\\Life After People (2008)": 856319577,
@ -1486,7 +1493,7 @@
"P:\\movies\\I am Legend (2007)": 472399898, "P:\\movies\\I am Legend (2007)": 472399898,
"P:\\movies\\Seven Psychopaths (2012)": 787315239, "P:\\movies\\Seven Psychopaths (2012)": 787315239,
"P:\\movies\\Ron's Gone Wrong (2021)": 1027827258, "P:\\movies\\Ron's Gone Wrong (2021)": 1027827258,
"P:\\movies\\Paradise Records (2025)": 2155834535, "P:\\movies\\Paradise Records (2025)": 1051339618,
"P:\\movies\\The Nun (2018)": 876835728, "P:\\movies\\The Nun (2018)": 876835728,
"P:\\movies\\Mars Attacks! (1996)": 974084293, "P:\\movies\\Mars Attacks! (1996)": 974084293,
"P:\\movies\\How the Grinch Stole Christmas (2000)": 3268490830, "P:\\movies\\How the Grinch Stole Christmas (2000)": 3268490830,
@ -1579,8 +1586,9 @@
"P:\\movies\\The Phoenician Scheme (2025)": 2661907395, "P:\\movies\\The Phoenician Scheme (2025)": 2661907395,
"P:\\movies\\Cinderella (2021)": 1087262833, "P:\\movies\\Cinderella (2021)": 1087262833,
"P:\\movies\\The Lego Movie 2 The Second Part (2019)": 950172844, "P:\\movies\\The Lego Movie 2 The Second Part (2019)": 950172844,
"P:\\movies\\Meet the Fockers (2004)": 1495880216, "P:\\movies\\Meet the Fockers (2004)": 1639660403,
"P:\\movies\\The Bad Batch (2017)": 926871424, "P:\\movies\\The Bad Batch (2017)": 926871424,
"P:\\movies\\Forever Young (1992)": 977859032,
"P:\\movies\\Halloweentown (1998)": 810513129, "P:\\movies\\Halloweentown (1998)": 810513129,
"P:\\movies\\Silent Night (2023)": 1003667495, "P:\\movies\\Silent Night (2023)": 1003667495,
"P:\\movies\\Bridget Jones's Diary (2001)": 925436159, "P:\\movies\\Bridget Jones's Diary (2001)": 925436159,
@ -1655,7 +1663,7 @@
"P:\\movies\\Vacation (2015)": 882534348, "P:\\movies\\Vacation (2015)": 882534348,
"P:\\movies\\Canadian Bacon (1995)": 915905234, "P:\\movies\\Canadian Bacon (1995)": 915905234,
"P:\\movies\\Blue Beetle (2023)": 1949820350, "P:\\movies\\Blue Beetle (2023)": 1949820350,
"P:\\movies\\The Baker (2023)": 5497792586, "P:\\movies\\The Baker (2023)": 816561611,
"P:\\movies\\Jurassic Park (1993)": 793306783, "P:\\movies\\Jurassic Park (1993)": 793306783,
"P:\\movies\\Code 3 (2025)": 962773414, "P:\\movies\\Code 3 (2025)": 962773414,
"P:\\movies\\Memory (2022)": 1098424408, "P:\\movies\\Memory (2022)": 1098424408,
@ -1685,7 +1693,7 @@
"P:\\movies\\S.W.A.T. (2019)": 1056909910, "P:\\movies\\S.W.A.T. (2019)": 1056909910,
"P:\\movies\\The Persian Version (2023)": 1036376746, "P:\\movies\\The Persian Version (2023)": 1036376746,
"P:\\movies\\Bambi II (2006)": 643557348, "P:\\movies\\Bambi II (2006)": 643557348,
"P:\\movies\\Pirates of the Caribbean - The Curse of the Black Pearl (2003)": 6749680201, "P:\\movies\\Pirates of the Caribbean - The Curse of the Black Pearl (2003)": 6164584510,
"P:\\movies\\Ordinary World (2016)": 1414665447, "P:\\movies\\Ordinary World (2016)": 1414665447,
"P:\\movies\\Bad Boys for Life (2020)": 1193361085, "P:\\movies\\Bad Boys for Life (2020)": 1193361085,
"P:\\movies\\Pok\u00e9mon - Lucario and the Mystery of Mew (2005)": 2253435788, "P:\\movies\\Pok\u00e9mon - Lucario and the Mystery of Mew (2005)": 2253435788,
@ -1769,7 +1777,7 @@
"P:\\movies\\The Bikeriders (2024)": 1121777975, "P:\\movies\\The Bikeriders (2024)": 1121777975,
"P:\\movies\\Stuber (2019)": 861709290, "P:\\movies\\Stuber (2019)": 861709290,
"P:\\movies\\John Wick - Chapter 4 (2023)": 4680013949, "P:\\movies\\John Wick - Chapter 4 (2023)": 4680013949,
"P:\\movies\\Pirates of the Caribbean - On Stranger Tides (2011)": 2317926572, "P:\\movies\\Pirates of the Caribbean - On Stranger Tides (2011)": 4297016060,
"P:\\movies\\Ghost (1990)": 872499373, "P:\\movies\\Ghost (1990)": 872499373,
"P:\\movies\\Confessions of a Sociopathic Social Climber (2005)": 820262358, "P:\\movies\\Confessions of a Sociopathic Social Climber (2005)": 820262358,
"P:\\movies\\Fatherhood (2021)": 1050118813, "P:\\movies\\Fatherhood (2021)": 1050118813,
@ -2135,6 +2143,7 @@
"P:\\movies\\Beauty and the Beast - Extended Edition (1991)": 575996197, "P:\\movies\\Beauty and the Beast - Extended Edition (1991)": 575996197,
"P:\\movies\\R.I.P.D. 2 - Rise of the Damned (2022)": 921792650, "P:\\movies\\R.I.P.D. 2 - Rise of the Damned (2022)": 921792650,
"P:\\movies\\Couples Retreat (2009)": 787204478, "P:\\movies\\Couples Retreat (2009)": 787204478,
"P:\\movies\\The Wedding Date (2005)": 857810936,
"P:\\movies\\The Girl Next Door UNRATED (2004)": 787262062, "P:\\movies\\The Girl Next Door UNRATED (2004)": 787262062,
"P:\\movies\\Downey Wrote That (2025)": 643153092, "P:\\movies\\Downey Wrote That (2025)": 643153092,
"P:\\movies\\The Nutty Professor (1996)": 681729259, "P:\\movies\\The Nutty Professor (1996)": 681729259,
@ -2185,7 +2194,7 @@
"P:\\movies\\Jurassic World - Fallen Kingdom (2018)": 1158321969, "P:\\movies\\Jurassic World - Fallen Kingdom (2018)": 1158321969,
"P:\\movies\\Moonlight (2016)": 851155837, "P:\\movies\\Moonlight (2016)": 851155837,
"P:\\movies\\Barbarella (1968)": 943578060, "P:\\movies\\Barbarella (1968)": 943578060,
"P:\\movies\\Small Soldiers (1998)": 5094073349, "P:\\movies\\Small Soldiers (1998)": 3036317509,
"P:\\movies\\Gran Torino (2008)": 788767144, "P:\\movies\\Gran Torino (2008)": 788767144,
"P:\\movies\\Enchanted (2007)": 955502916, "P:\\movies\\Enchanted (2007)": 955502916,
"P:\\movies\\Nate Bargatze - Hello World (2023)": 587515341, "P:\\movies\\Nate Bargatze - Hello World (2023)": 587515341,
@ -2217,7 +2226,7 @@
"P:\\movies\\Ride 'Em Cowboy (1942)": 826176530, "P:\\movies\\Ride 'Em Cowboy (1942)": 826176530,
"P:\\movies\\South Park the Streaming Wars (2022)": 462635235, "P:\\movies\\South Park the Streaming Wars (2022)": 462635235,
"P:\\movies\\The Quintessential Quintuplets Movie (2022)": 2671283313, "P:\\movies\\The Quintessential Quintuplets Movie (2022)": 2671283313,
"P:\\movies\\John Wick - Chapter 2 (2017)": 6452174217, "P:\\movies\\John Wick - Chapter 2 (2017)": 2910556976,
"P:\\movies\\Hitman Agent 47 (2015)": 586386449, "P:\\movies\\Hitman Agent 47 (2015)": 586386449,
"P:\\movies\\Paul (2011)": 731417836, "P:\\movies\\Paul (2011)": 731417836,
"P:\\movies\\Butter (2012)": 809373699, "P:\\movies\\Butter (2012)": 809373699,
@ -2384,7 +2393,7 @@
"P:\\movies\\Halloweentown II - Kalabar's Revenge (2001)": 1052744699, "P:\\movies\\Halloweentown II - Kalabar's Revenge (2001)": 1052744699,
"P:\\movies\\The Survivors (1983)": 883588130, "P:\\movies\\The Survivors (1983)": 883588130,
"P:\\movies\\A Bad Moms Christmas (2017)": 800570325, "P:\\movies\\A Bad Moms Christmas (2017)": 800570325,
"P:\\movies\\Meet the Parents (2000)": 2131659488, "P:\\movies\\Meet the Parents (2000)": 1167666740,
"P:\\movies\\Slayers (2022)": 849805353, "P:\\movies\\Slayers (2022)": 849805353,
"P:\\movies\\The Good Nurse (2022)": 840206859, "P:\\movies\\The Good Nurse (2022)": 840206859,
"P:\\movies\\The Death and Life of Bobby Z (2007)": 788294208, "P:\\movies\\The Death and Life of Bobby Z (2007)": 788294208,
@ -2478,7 +2487,7 @@
"P:\\movies\\Spider-Man - Far From Home (2019)": 1838406206, "P:\\movies\\Spider-Man - Far From Home (2019)": 1838406206,
"P:\\movies\\Jack Reacher (2012)": 2051597479, "P:\\movies\\Jack Reacher (2012)": 2051597479,
"P:\\movies\\The Meg (2018)": 1019483886, "P:\\movies\\The Meg (2018)": 1019483886,
"P:\\movies\\Violent Night (2022)": 5106244959, "P:\\movies\\Violent Night (2022)": 1906909883,
"P:\\movies\\House of Gucci (2021)": 1519261888, "P:\\movies\\House of Gucci (2021)": 1519261888,
"P:\\movies\\Mulholland Falls (1996)": 852069037, "P:\\movies\\Mulholland Falls (1996)": 852069037,
"P:\\movies\\The Golden Child (1986)": 833761735, "P:\\movies\\The Golden Child (1986)": 833761735,
@ -2501,7 +2510,7 @@
"P:\\movies\\The Good, the Bart, and the Loki (2021)": 43984236, "P:\\movies\\The Good, the Bart, and the Loki (2021)": 43984236,
"P:\\movies\\Clerks III (2022)": 963907340, "P:\\movies\\Clerks III (2022)": 963907340,
"P:\\movies\\M3GAN 2.0 (2025)": 1158862629, "P:\\movies\\M3GAN 2.0 (2025)": 1158862629,
"P:\\movies\\Belle (2021)": 6192364946, "P:\\movies\\Belle (2021)": 1967787278,
"P:\\movies\\Minamata (2020)": 1104986233, "P:\\movies\\Minamata (2020)": 1104986233,
"P:\\movies\\Alive (1993)": 1216643767, "P:\\movies\\Alive (1993)": 1216643767,
"P:\\movies\\The Princess and the Frog (2009)": 734834721, "P:\\movies\\The Princess and the Frog (2009)": 734834721,
@ -2510,7 +2519,6 @@
"P:\\movies\\Inside Llewyn Davis (2013)": 849607966, "P:\\movies\\Inside Llewyn Davis (2013)": 849607966,
"P:\\movies\\The Addams Family 2 (2021)": 892624431, "P:\\movies\\The Addams Family 2 (2021)": 892624431,
"P:\\movies\\She's Out of My League (2010)": 682549102, "P:\\movies\\She's Out of My League (2010)": 682549102,
"P:\\movies\\AJR - Somewhere in the sky (2025)": 2919401404,
"P:\\movies\\Minions & More 1 (2022)": 465025396, "P:\\movies\\Minions & More 1 (2022)": 465025396,
"P:\\movies\\Blade Runner 2049 (2017)": 2693638088, "P:\\movies\\Blade Runner 2049 (2017)": 2693638088,
"P:\\movies\\Twilight Saga (2008)": 733993564, "P:\\movies\\Twilight Saga (2008)": 733993564,
@ -2607,7 +2615,7 @@
"P:\\movies\\Youngblood (1986)": 978057487, "P:\\movies\\Youngblood (1986)": 978057487,
"P:\\movies\\Inglourious Basterds (2009)": 2855779029, "P:\\movies\\Inglourious Basterds (2009)": 2855779029,
"P:\\movies\\Black or White (2014)": 911771671, "P:\\movies\\Black or White (2014)": 911771671,
"P:\\movies\\AJR - The Maybe Man Immersive Concert Experience (2024)": 4590528226, "P:\\movies\\AJR - The Maybe Man Immersive Concert Experience (2024)": 4591719568,
"P:\\movies\\Animal House (1978)": 787489930, "P:\\movies\\Animal House (1978)": 787489930,
"P:\\movies\\Cinderella (2015)": 1763561462, "P:\\movies\\Cinderella (2015)": 1763561462,
"P:\\movies\\I'll Be Home for Christmas (1998)": 769320107, "P:\\movies\\I'll Be Home for Christmas (1998)": 769320107,
@ -2630,7 +2638,7 @@
"P:\\movies\\The Master of Disguise (2002)": 1343424184, "P:\\movies\\The Master of Disguise (2002)": 1343424184,
"P:\\movies\\DodgeBall - A True Underdog Story (2004)": 787609348, "P:\\movies\\DodgeBall - A True Underdog Story (2004)": 787609348,
"P:\\movies\\The Emperor's New Groove (2000)": 726824390, "P:\\movies\\The Emperor's New Groove (2000)": 726824390,
"P:\\movies\\John Wick - Chapter 3 - Parabellum (2019)": 7853540695, "P:\\movies\\John Wick - Chapter 3 - Parabellum (2019)": 3857527829,
"P:\\movies\\Aloha (2015)": 849543660, "P:\\movies\\Aloha (2015)": 849543660,
"P:\\movies\\Thumbsucker (2005)": 925537380, "P:\\movies\\Thumbsucker (2005)": 925537380,
"P:\\movies\\Ghosted (2023)": 2318216001, "P:\\movies\\Ghosted (2023)": 2318216001,
@ -2705,6 +2713,7 @@
"P:\\movies\\Palm Springs (2020)": 1609086346, "P:\\movies\\Palm Springs (2020)": 1609086346,
"P:\\movies\\Captain America - The First Avenger (2011)": 1713875628, "P:\\movies\\Captain America - The First Avenger (2011)": 1713875628,
"P:\\movies\\Clear History (2013)": 791420953, "P:\\movies\\Clear History (2013)": 791420953,
"P:\\movies\\Interstate 60 (2002)": 1079307887,
"P:\\movies\\Jeff Dunham - Me the People (2022)": 404337420, "P:\\movies\\Jeff Dunham - Me the People (2022)": 404337420,
"P:\\movies\\Scary Movie 2 (2001)": 794281384, "P:\\movies\\Scary Movie 2 (2001)": 794281384,
"P:\\movies\\About My Father (2023)": 1609106023, "P:\\movies\\About My Father (2023)": 1609106023,

View File

@ -1,322 +1,322 @@
{ {
"P:\\tv\\1883": 4514294832,
"P:\\tv\\1923": 22125507023,
"P:\\tv\\3 Body Problem": 11369334730,
"P:\\tv\\30 Rock (2006)": 81412969909,
"P:\\tv\\Abbott Elementary (2021)": 24595462535,
"P:\\tv\\Adults (2025)": 6845585714,
"P:\\tv\\Adventuring Academy": 62196997373,
"P:\\tv\\Agatha All Along": 3411637969,
"P:\\tv\\Alien - Earth (2025)": 2926145405,
"P:\\tv\\Amazing Stories (2020)": 4281304451,
"P:\\tv\\American Gods (2017)": 43921706762,
"P:\\tv\\American Horror Story": 142468660014,
"P:\\tv\\Andor (2022)": 25679584728,
"P:\\tv\\Arcane (2021)": 19588567847,
"P:\\tv\\Assembly Required (2021)": 5737519036,
"P:\\tv\\Avenue 5": 12572813494,
"P:\\tv\\Bad Monkey": 7767595411,
"P:\\tv\\Ballers": 13002096756,
"P:\\tv\\Band of Brothers (2001)": 15129362120,
"P:\\tv\\Banshee (2013)": 25030541772,
"P:\\tv\\Barry": 31934844666,
"P:\\tv\\BattleBots": 61,
"P:\\tv\\BattleBots (2015)": 69,
"P:\\tv\\Being Human (2011)": 66311454464,
"P:\\tv\\Belgravia - The Next Chapter": 8340040939,
"P:\\tv\\Below Deck": 47516712212,
"P:\\tv\\Below Deck Down Under (2022)": 36006759742,
"P:\\tv\\Below Deck Mediterranean": 39902249615,
"P:\\tv\\Below Deck Sailing Yacht": 12706704039,
"P:\\tv\\Better Call Saul": 31152560439,
"P:\\tv\\Billions": 31141419259,
"P:\\tv\\Billy the Kid": 44803721006,
"P:\\tv\\Black Bird (2022)": 5893929480,
"P:\\tv\\Black Sails (2014)": 11356486450,
"P:\\tv\\Brooklyn Nine Nine": 45722673163,
"P:\\tv\\Bupkis": 13034439710,
"P:\\tv\\Canada's Drag Race": 103586850759,
"P:\\tv\\Canada's Drag Race vs The World": 7844155647,
"P:\\tv\\Catch-22": 7113496871,
"P:\\tv\\Chad Powers (2025)": 2474659236,
"P:\\tv\\Chilling Adventures of Sabrina (2018)": 23147355371,
"P:\\tv\\Chuck": 32193192829,
"P:\\tv\\Citadel": 2339699246,
"P:\\tv\\Citadel - Diana": 13304679453,
"P:\\tv\\Cobra Kai": 39761471967,
"P:\\tv\\Continuum (2012)": 29352883496,
"P:\\tv\\Countdown (2025)": 8935252687,
"P:\\tv\\Counterpart": 4875616955,
"P:\\tv\\Creature Commandos (2024)": 2331424358,
"P:\\tv\\Crowd Control": 9644641207,
"P:\\tv\\Cyberpunk - Edgerunners (2022)": 11313875182,
"P:\\tv\\Daredevil - Born Again (2025)": 7647367391,
"P:\\tv\\Dark Side of the Ring": 11863132534,
"P:\\tv\\Dateline NBC (1992)": 19267231607,
"P:\\tv\\Death and Other Details": 17844763765,
"P:\\tv\\Detroiters (2017)": 33750584701,
"P:\\tv\\Dimension 20": 557729281243,
"P:\\tv\\Dimension 20's Adventuring Party": 12002285238,
"P:\\tv\\Dirk Gently's Holistic Detective Agency (2016)": 11935610182,
"P:\\tv\\Dirty Laundry": 38036591078,
"P:\\tv\\Doctor Who (2005)": 5820708419,
"P:\\tv\\Dopesick": 2571994785,
"P:\\tv\\DOTA - Dragon's Blood (2021)": 12538510766,
"P:\\tv\\Dracula (2020)": 2147285239,
"P:\\tv\\Dune - Prophecy": 3330003290,
"P:\\tv\\Dungeons & Dragons": 6660128393,
"P:\\tv\\Dwight in Shining Armor": 75,
"P:\\tv\\English Teacher": 7603165476,
"P:\\tv\\Euphoria": 40925172559,
"P:\\tv\\Extraordinary": 6934203888,
"P:\\tv\\Extrapolations": 6155965724,
"P:\\tv\\Face Off (2011)": 83155672195,
"P:\\tv\\Fallen (2024)": 4161867429,
"P:\\tv\\Fallout": 19686023936,
"P:\\tv\\Fargo (2014)": 93792752129,
"P:\\tv\\Father Brown": 18896564477,
"P:\\tv\\Fired on Mars (2023)": 3590992124,
"P:\\tv\\Firefly (2002)": 7517428895,
"P:\\tv\\From Dusk Till Dawn - The Series (2014)": 5360771338,
"P:\\tv\\Galavant": 12147863291,
"P:\\tv\\Game Changer": 38317757866,
"P:\\tv\\Game Changers (2024)": 5880504271,
"P:\\tv\\Game Of Thrones": 119681469870,
"P:\\tv\\Gastronauts": 9365810750,
"P:\\tv\\Gen V (2023)": 16871757804,
"P:\\tv\\Ghosts (2019)": 40703143881,
"P:\\tv\\Ghosts (2021)": 4574333812,
"P:\\tv\\Goosebumps (2023)": 8257419062,
"P:\\tv\\Gordon Ramsay's Food Stars (2023)": 6344621632,
"P:\\tv\\Government Cheese (2025)": 15970704500,
"P:\\tv\\Gravity Falls": 31900305156,
"P:\\tv\\Halo": 6961206915,
"P:\\tv\\Harley and the Davidsons": 76,
"P:\\tv\\Harley Quinn": 20857796821,
"P:\\tv\\Harry Potter - Wizards of Baking (2024)": 23545641052,
"P:\\tv\\Haunted Hotel (2025)": 4735071992,
"P:\\tv\\Hawkeye": 13524278345,
"P:\\tv\\Hazbin Hotel (2024)": 10906489515,
"P:\\tv\\Hero Inside (2023)": 7372329680, "P:\\tv\\Hero Inside (2023)": 7372329680,
"P:\\tv\\High Potential": 24339309461, "P:\\tv\\Below Deck": 47516712212,
"P:\\tv\\Hitmen (2020)": 12274410846,
"P:\\tv\\Home Economics": 14315967074,
"P:\\tv\\Home Improvement 1991": 48878774505,
"P:\\tv\\House of Guinness (2025)": 5444928896,
"P:\\tv\\House of the Dragon": 23959073249,
"P:\\tv\\iCarly (2021)": 19966043984,
"P:\\tv\\Impractical Jokers": 13357380400,
"P:\\tv\\In the Dark (2019)": 2555891397,
"P:\\tv\\Ink Master": 23329086486,
"P:\\tv\\Interior Chinatown": 3167640001,
"P:\\tv\\Invincible (2021)": 19742824176,
"P:\\tv\\Ironheart (2025)": 3153557870,
"P:\\tv\\Its Always Sunny in Philadelphia": 84650830434,
"P:\\tv\\Jentry Chau vs. the Underworld (2024)": 1406237358,
"P:\\tv\\Junior Taskmaster (2024)": 4133620030,
"P:\\tv\\Jury Duty": 8010062372,
"P:\\tv\\Kaos": 5164057710,
"P:\\tv\\Kevin Can F-k Himself": 11614889793,
"P:\\tv\\Killer Cakes": 3673781461,
"P:\\tv\\Kim's Convenience": 30475634673,
"P:\\tv\\Kitchen Nightmares UK": 11563663098,
"P:\\tv\\Kitchen Nightmares US": 56092851597,
"P:\\tv\\Knuckles": 2140786440,
"P:\\tv\\Krypton (2018)": 10875524680,
"P:\\tv\\Landman (2024)": 35220290035,
"P:\\tv\\Last Man Standing": 49393251846,
"P:\\tv\\Lawmen - Bass Reeves (2023)": 5363156538,
"P:\\tv\\Lessons in Chemistry (2023)": 5485801173,
"P:\\tv\\Letterkenny": 63,
"P:\\tv\\Life After People (2009)": 45628647899,
"P:\\tv\\Loki": 20082144632,
"P:\\tv\\Love Island (US) (2019)": 20699120877,
"P:\\tv\\Love, Death & Robots (2019)": 8204860116,
"P:\\tv\\Lucky Hank": 7336222432,
"P:\\tv\\Ludwig (2024)": 2670615425,
"P:\\tv\\Made For Love (2021)": 2211136772,
"P:\\tv\\Make Some Noise": 25555591381,
"P:\\tv\\Man Down (2013)": 5077144151,
"P:\\tv\\Married at First Sight (2014)": 30275711911,
"P:\\tv\\Married... with Children (1987)": 64228823786,
"P:\\tv\\Marvel's The Punisher (2017)": 32242478897,
"P:\\tv\\Matlock (2024)": 34470939613,
"P:\\tv\\Mayor of Kingstown (2021)": 65464041666,
"P:\\tv\\Mighty Nein (2025)": 6138965943,
"P:\\tv\\MobLand (2025)": 6622179548,
"P:\\tv\\Modern Family": 82788065200,
"P:\\tv\\Monarch Legacy of Monsters": 18371826949,
"P:\\tv\\Monet's Slumber Party": 8253206091,
"P:\\tv\\Moon Knight": 10976093361,
"P:\\tv\\Mr. & Mrs. Smith (2024)": 5316681916,
"P:\\tv\\Murder She Wrote": 12095973826,
"P:\\tv\\Murderbot (2025)": 18338040970,
"P:\\tv\\Mythic Quest": 16965795814,
"P:\\tv\\New Girl": 40676856398,
"P:\\tv\\Nobody Wants This": 11516933757,
"P:\\tv\\Obi-Wan Kenobi": 13867986923,
"P:\\tv\\One More Time (2024)": 6434473461,
"P:\\tv\\Only Murders in the Building (2021)": 2379838148,
"P:\\tv\\Our Flag Means Death": 2107045664,
"P:\\tv\\Outlander": 27364180668,
"P:\\tv\\Over the Garden Wall": 2937573633,
"P:\\tv\\Pantheon": 13397374449,
"P:\\tv\\Paradise (2025)": 8024209737,
"P:\\tv\\Parks and Recreation": 37277190974,
"P:\\tv\\Parlor Room": 12022280605,
"P:\\tv\\Passion for punchlines": 75514795,
"P:\\tv\\Peacemaker (2022)": 13199970800,
"P:\\tv\\Percy Jackson and the Olympians": 3558450335,
"P:\\tv\\Platonic (2023)": 17488146510,
"P:\\tv\\Pok\u00e9mon Concierge (2023)": 1134616527,
"P:\\tv\\Poppa\u2019s House": 13794748297,
"P:\\tv\\Power (2014)": 20414619656,
"P:\\tv\\Quantum Leap (1989)": 39284023472,
"P:\\tv\\Quantum Leap 2022": 8902776416,
"P:\\tv\\Quiet On Set - The Dark Side Of Kids TV": 12191520028,
"P:\\tv\\Raised by wolves": 9720677524,
"P:\\tv\\Reacher (2022)": 17521873037,
"P:\\tv\\Resident Alien (2021)": 17522605407,
"P:\\tv\\Rick and Morty": 31672318625,
"P:\\tv\\Royal Pains (2009)": 1247586112,
"P:\\tv\\Running Man": 10279755878,
"P:\\tv\\Rupaul's Drag Race": 57149739065,
"P:\\tv\\Rupaul's Drag Race All Stars": 60579323023,
"P:\\tv\\RuPaul's Drag Race Down Under": 27454793482,
"P:\\tv\\Rupaul's Drag Race UK": 110914388896,
"P:\\tv\\Rupaul's Drag Race Vegas Revue": 2532474468,
"P:\\tv\\Rupauls Drag Race UK vs The World": 35504142221,
"P:\\tv\\SAS Rogue Heroes (2022)": 10733559643,
"P:\\tv\\Saving Hope": 33116225358,
"P:\\tv\\Scenes from a Marriage (US)": 12493986505,
"P:\\tv\\Schitt's Creek": 9325109901,
"P:\\tv\\Schmigadoon!": 6206632733,
"P:\\tv\\SCORPION": 54081802764,
"P:\\tv\\Secret Celebrity RuPaul's Drag Race": 4211193920,
"P:\\tv\\Secret Level": 2810124465,
"P:\\tv\\See": 12316511887,
"P:\\tv\\Selfie": 5013734266,
"P:\\tv\\Severance": 15044806873,
"P:\\tv\\She-Hulk Attorney at Law": 10233633417,
"P:\\tv\\Shetland": 18537045340,
"P:\\tv\\Shifting Gears (2025)": 12649531141,
"P:\\tv\\Shoresy": 9701736850,
"P:\\tv\\Shrinking (2023)": 17293593983,
"P:\\tv\\Sh\u014dgun": 20899988683,
"P:\\tv\\Silicon Valley (2014)": 63657428121,
"P:\\tv\\Silo (2023)": 12897630564,
"P:\\tv\\Sirens (2025)": 4246622090,
"P:\\tv\\Smartypants": 15959708127,
"P:\\tv\\Smiling Friends": 5633340834,
"P:\\tv\\Solar Opposites": 1138214210,
"P:\\tv\\Son of Zorn (2016)": 6780978712,
"P:\\tv\\South Park": 70261225261,
"P:\\tv\\Spartacus": 75639017886,
"P:\\tv\\Special Ops Lioness": 9765393961,
"P:\\tv\\Squid Game (2021)": 22082475135,
"P:\\tv\\St. Denis Medical (2024)": 18704263469,
"P:\\tv\\Star Strek Strange New Worlds": 13781151928,
"P:\\tv\\Star Trek Lower Decks": 33090597113,
"P:\\tv\\Star Wars - Skeleton Crew (2024)": 2940779001,
"P:\\tv\\Stargirl": 9507100884,
"P:\\tv\\Station Eleven": 2708694925,
"P:\\tv\\Stranger Things (2016)": 64934698827,
"P:\\tv\\Suits LA (2025)": 22274831381,
"P:\\tv\\Superman and Lois": 44881535930,
"P:\\tv\\Supernatural": 377851589424,
"P:\\tv\\Sweetpea": 2706241673,
"P:\\tv\\Swimming with Sharks": 4426141798,
"P:\\tv\\Taboo (2017)": 19309841226,
"P:\\tv\\Taskmaster": 142193364333,
"P:\\tv\\Taskmaster (CA) (2022)": 2431664380,
"P:\\tv\\Taskmaster (NZ)": 71323320898,
"P:\\tv\\Taskmaster - Champion of Champions": 2700754514,
"P:\\tv\\Taskmaster AU": 20527610746,
"P:\\tv\\Taylor (2025)": 2621206209,
"P:\\tv\\Ted (2024)": 3024624414,
"P:\\tv\\Ted Lasso (2020)": 52046307136,
"P:\\tv\\Terminator Zero": 3384699699,
"P:\\tv\\The 10th Kingdom (2000)": 14174589505,
"P:\\tv\\The Amazing Digital Circus (2023)": 4739070191,
"P:\\tv\\The Bachelor": 40368931577,
"P:\\tv\\The Bachelorette": 9927266246,
"P:\\tv\\The Bear (2022)": 43665628138,
"P:\\tv\\The Big Door Prize": 2314902686,
"P:\\tv\\The Bondsman (2025)": 3112664353,
"P:\\tv\\The Book of Boba Fett": 12039417291,
"P:\\tv\\The Boys": 68010010167,
"P:\\tv\\The Chosen (2019)": 54241850899,
"P:\\tv\\The Closer": 47449608535,
"P:\\tv\\The Consultant (2023)": 74,
"P:\\tv\\The Continental (2023)": 1920206807,
"P:\\tv\\The Day of the Jackal (2024)": 17787097381,
"P:\\tv\\The Dragon Dentist": 11317084093,
"P:\\tv\\The Drew Carey Show (1995)": 70,
"P:\\tv\\The Edge of Sleep": 1358235145,
"P:\\tv\\The Eternaut": 17178505929,
"P:\\tv\\The Falcon and The Winter Soldier (2021)": 11657055937,
"P:\\tv\\The Fall of Diddy (2025)": 2431035593,
"P:\\tv\\The Fall of the House of Usher (2023)": 16454192941,
"P:\\tv\\The Forsytes (2025)": 4034792830,
"P:\\tv\\The Franchise (2024)": 2981270395,
"P:\\tv\\The Gentlemen (2024)": 5224500371,
"P:\\tv\\The Gilded Age": 90505242840,
"P:\\tv\\The Goes Wrong Show (2019)": 3676343887,
"P:\\tv\\The Good Lord Bird (2020)": 5619421375,
"P:\\tv\\The Great (2020)": 22361386693,
"P:\\tv\\The Great British Bake Off": 78,
"P:\\tv\\The IT Crowd (2006)": 9239572772,
"P:\\tv\\The Journal of the Mysterious Creatures (2019)": 92,
"P:\\tv\\The Last of Us": 30545352719,
"P:\\tv\\The Legend of Vox Machina": 25197294503,
"P:\\tv\\The Lord of the Rings - The Rings of Power": 12834498889,
"P:\\tv\\The Mandalorian": 36487773789,
"P:\\tv\\The Morning Show": 94311701751,
"P:\\tv\\The Newsroom": 27756667258,
"P:\\tv\\The Now": 836886747,
"P:\\tv\\The Offer": 9070667475,
"P:\\tv\\The Office (US)": 161867626607,
"P:\\tv\\The Old Man (2022)": 26139845941,
"P:\\tv\\The Originals (2013)": 72912846985,
"P:\\tv\\The Paper (2025)": 8102218176,
"P:\\tv\\The Penguin": 4459075060, "P:\\tv\\The Penguin": 4459075060,
"P:\\tv\\The Pretender": 18425629462, "P:\\tv\\Banshee (2013)": 25030541772,
"P:\\tv\\The Queen's Gambit": 4100494817, "P:\\tv\\Dungeons & Dragons": 6660128393,
"P:\\tv\\The Rain (2018)": 2941174698, "P:\\tv\\Made For Love (2021)": 2211136772,
"P:\\tv\\The Santa Clauses (2022)": 6400385164, "P:\\tv\\Sirens (2025)": 4246622090,
"P:\\tv\\The Second Best Hospital in the Galaxy (2024)": 3636394169, "P:\\tv\\Landman (2024)": 35968103808,
"P:\\tv\\The Split": 7970767632, "P:\\tv\\Last Man Standing": 49393251846,
"P:\\tv\\The Studio (2025)": 11530554023, "P:\\tv\\Alien - Earth (2025)": 2926145405,
"P:\\tv\\The Take": 6020370013, "P:\\tv\\The Big Door Prize": 2314902686,
"P:\\tv\\The Terminal List - Dark Wolf (2025)": 9939046560, "P:\\tv\\Government Cheese (2025)": 15970704500,
"P:\\tv\\The Traitors (US) (2023)": 48149750078, "P:\\tv\\In the Dark (2019)": 2555891397,
"P:\\tv\\The Trunk (2024)": 16810949304,
"P:\\tv\\The Umbrella Academy": 55348092191,
"P:\\tv\\Time Bandits (2024)": 6997478287,
"P:\\tv\\Tires (2024)": 5375794389,
"P:\\tv\\Titans (2018)": 31986198137,
"P:\\tv\\Tokyo Override (2024)": 3802255332,
"P:\\tv\\Tomb Raider - The Legend of Lara Croft": 9341088252,
"P:\\tv\\Tulsa King": 41351406080, "P:\\tv\\Tulsa King": 41351406080,
"P:\\tv\\Twisted Metal (2023)": 12547412897, "P:\\tv\\Dopesick": 2571994785,
"P:\\tv\\Um, Actually": 12360993522, "P:\\tv\\Taylor (2025)": 2621206209,
"P:\\tv\\Unstable": 5444623642, "P:\\tv\\Star Trek Lower Decks": 33090597113,
"P:\\tv\\Utopia (AU)": 8691287022, "P:\\tv\\Face Off (2011)": 83155672195,
"P:\\tv\\Very Important People": 12237876110, "P:\\tv\\Catch-22": 7113496871,
"P:\\tv\\Vice Principals (2016)": 18406955713, "P:\\tv\\Canada's Drag Race": 106759553819,
"P:\\tv\\Vikings (2013)": 194095449878, "P:\\tv\\Over the Garden Wall": 2937573633,
"P:\\tv\\Villainous (2017)": 1961793524, "P:\\tv\\The Traitors (US) (2023)": 48149750078,
"P:\\tv\\Walker": 5492500161, "P:\\tv\\1923": 22125507023,
"P:\\tv\\Wandavision": 10099450034, "P:\\tv\\Loki": 20082144632,
"P:\\tv\\Welcome to Chippendales (2022)": 10423545837, "P:\\tv\\House of the Dragon": 23959073249,
"P:\\tv\\Welcome to Wrexham": 66664948104, "P:\\tv\\The Trunk (2024)": 16810949304,
"P:\\tv\\What If": 21312022582, "P:\\tv\\The Chosen (2019)": 54241850899,
"P:\\tv\\Wildemount Wildlings (2025)": 3348907992, "P:\\tv\\Lucky Hank": 7336222432,
"P:\\tv\\Winning Time - The Rise of the Lakers Dynasty (2022)": 37911197652, "P:\\tv\\Station Eleven": 2708694925,
"P:\\tv\\Kitchen Nightmares UK": 11563663098,
"P:\\tv\\The Good Lord Bird (2020)": 5619421375,
"P:\\tv\\Wolf Pack": 6844099384, "P:\\tv\\Wolf Pack": 6844099384,
"P:\\tv\\WondLa": 1399628000, "P:\\tv\\Below Deck Mediterranean": 40713122628,
"P:\\tv\\Worst Cooks in America (2010)": 22063867049, "P:\\tv\\The Old Man (2022)": 26139845941,
"P:\\tv\\Schitt's Creek": 9325109901,
"P:\\tv\\Mr. & Mrs. Smith (2024)": 5316681916,
"P:\\tv\\Percy Jackson and the Olympians": 3558450335,
"P:\\tv\\Firefly (2002)": 7517428895,
"P:\\tv\\Ballers": 13002096756,
"P:\\tv\\Bupkis": 13034439710,
"P:\\tv\\The Offer": 9070667475,
"P:\\tv\\Life After People (2009)": 45628647899,
"P:\\tv\\The Lord of the Rings - The Rings of Power": 12834498889,
"P:\\tv\\Paradise (2025)": 8024209737,
"P:\\tv\\Nobody Wants This": 11516933757,
"P:\\tv\\Shrinking (2023)": 17293593983,
"P:\\tv\\Hawkeye": 13524278345,
"P:\\tv\\Home Economics": 14315967074,
"P:\\tv\\Time Bandits (2024)": 6997478287,
"P:\\tv\\Lessons in Chemistry (2023)": 5485801173,
"P:\\tv\\1883": 4514294832,
"P:\\tv\\Love, Death & Robots (2019)": 8204860116,
"P:\\tv\\The Legend of Vox Machina": 25197294503,
"P:\\tv\\Harry Potter - Wizards of Baking (2024)": 23545641052,
"P:\\tv\\The Bachelor": 40368931577,
"P:\\tv\\American Horror Story": 142468660014,
"P:\\tv\\Yellowstone (2018)": 89724605866, "P:\\tv\\Yellowstone (2018)": 89724605866,
"P:\\tv\\St. Denis Medical (2024)": 19403375683,
"P:\\tv\\Cobra Kai": 39761471967,
"P:\\tv\\Power (2014)": 20414619656,
"P:\\tv\\The Originals (2013)": 72912846985,
"P:\\tv\\The Edge of Sleep": 1358235145,
"P:\\tv\\3 Body Problem": 11369334730,
"P:\\tv\\New Girl": 40676856398,
"P:\\tv\\Assembly Required (2021)": 5737519036,
"P:\\tv\\30 Rock (2006)": 81412969909,
"P:\\tv\\Rupauls Drag Race UK vs The World": 35504142221,
"P:\\tv\\Daredevil - Born Again (2025)": 7647367391,
"P:\\tv\\Brooklyn Nine Nine": 45722673163,
"P:\\tv\\Taskmaster - Champion of Champions": 2700754514,
"P:\\tv\\Kim's Convenience": 30475634673,
"P:\\tv\\The Office (US)": 161867626607,
"P:\\tv\\Stranger Things (2016)": 66712664909,
"P:\\tv\\Rupaul's Drag Race Vegas Revue": 2532474468,
"P:\\tv\\The Umbrella Academy": 55348092191,
"P:\\tv\\Secret Celebrity RuPaul's Drag Race": 4211193920,
"P:\\tv\\Andor (2022)": 25679584728,
"P:\\tv\\The Bondsman (2025)": 3112664353,
"P:\\tv\\Ghosts (2021)": 4574333812,
"P:\\tv\\Interior Chinatown": 3167640001,
"P:\\tv\\Selfie": 5013734266,
"P:\\tv\\Supernatural": 209274293691,
"P:\\tv\\Superman and Lois": 44881535930,
"P:\\tv\\Black Sails (2014)": 11356486450,
"P:\\tv\\Taskmaster (CA) (2022)": 2431664380,
"P:\\tv\\The Last of Us": 30545352719,
"P:\\tv\\Halo": 6961206915,
"P:\\tv\\Home Improvement 1991": 48878774505,
"P:\\tv\\Detroiters (2017)": 33750584701,
"P:\\tv\\Wildemount Wildlings (2025)": 3348907992,
"P:\\tv\\Terminator Zero": 3384699699,
"P:\\tv\\Um, Actually": 12360993522,
"P:\\tv\\The Rain (2018)": 2941174698,
"P:\\tv\\Harley Quinn": 20857796821,
"P:\\tv\\Lawmen - Bass Reeves (2023)": 5363156538,
"P:\\tv\\Parks and Recreation": 37277190974,
"P:\\tv\\Mythic Quest": 16965795814,
"P:\\tv\\Invincible (2021)": 19742824176,
"P:\\tv\\The Bear (2022)": 43665628138,
"P:\\tv\\Jentry Chau vs. the Underworld (2024)": 1406237358,
"P:\\tv\\Countdown (2025)": 8935252687,
"P:\\tv\\The Great British Bake Off": 78,
"P:\\tv\\Smartypants": 15959708127,
"P:\\tv\\Scenes from a Marriage (US)": 12493986505,
"P:\\tv\\The Franchise (2024)": 2981270395,
"P:\\tv\\Chad Powers (2025)": 2474659236,
"P:\\tv\\Doctor Who (2005)": 5820708419,
"P:\\tv\\Bad Monkey": 7767595411,
"P:\\tv\\Swimming with Sharks": 4426141798,
"P:\\tv\\English Teacher": 7603165476,
"P:\\tv\\Resident Alien (2021)": 17522605407,
"P:\\tv\\Krypton (2018)": 10875524680,
"P:\\tv\\Vikings (2013)": 194095449878,
"P:\\tv\\Arcane (2021)": 19588567847,
"P:\\tv\\Ludwig (2024)": 2670615425,
"P:\\tv\\Canada's Drag Race vs The World": 7844155647,
"P:\\tv\\BattleBots (2015)": 69,
"P:\\tv\\Abbott Elementary (2021)": 24595462535,
"P:\\tv\\Billy the Kid": 44803721006,
"P:\\tv\\Quantum Leap 2022": 8902776416,
"P:\\tv\\Obi-Wan Kenobi": 13867986923,
"P:\\tv\\Matlock (2024)": 34470939613,
"P:\\tv\\The Fall of Diddy (2025)": 2431035593,
"P:\\tv\\Kaos": 5164057710,
"P:\\tv\\Shifting Gears (2025)": 13556293879,
"P:\\tv\\Saving Hope": 33116225358,
"P:\\tv\\Gen V (2023)": 16871757804,
"P:\\tv\\Below Deck Sailing Yacht": 12706704039,
"P:\\tv\\Monarch Legacy of Monsters": 18371826949,
"P:\\tv\\High Potential": 24845798484,
"P:\\tv\\Band of Brothers (2001)": 15129362120,
"P:\\tv\\Quantum Leap (1989)": 39284023472,
"P:\\tv\\Harley and the Davidsons": 76,
"P:\\tv\\Rupaul's Drag Race All Stars": 60579323023,
"P:\\tv\\Amazing Stories (2020)": 4281304451,
"P:\\tv\\Murder She Wrote": 12095973826,
"P:\\tv\\Kitchen Nightmares US": 56092851597,
"P:\\tv\\Game Changer": 38317757866,
"P:\\tv\\Taskmaster AU": 20527610746,
"P:\\tv\\Fallout": 20302317773,
"P:\\tv\\Young Sheldon": 21714069112, "P:\\tv\\Young Sheldon": 21714069112,
"P:\\tv\\Your Honor (2020)": 25879839349 "P:\\tv\\Vice Principals (2016)": 18406955713,
"P:\\tv\\Adventuring Academy": 62196997373,
"P:\\tv\\Solar Opposites": 1138214210,
"P:\\tv\\Pok\u00e9mon Concierge (2023)": 1134616527,
"P:\\tv\\Better Call Saul": 31152560439,
"P:\\tv\\Counterpart": 4875616955,
"P:\\tv\\The Paper (2025)": 8102218176,
"P:\\tv\\Chuck": 32193192829,
"P:\\tv\\The Bachelorette": 9927266246,
"P:\\tv\\Wandavision": 10099450034,
"P:\\tv\\Pantheon": 13397374449,
"P:\\tv\\The Gilded Age": 90505242840,
"P:\\tv\\Gastronauts": 9365810750,
"P:\\tv\\American Gods (2017)": 43921706762,
"P:\\tv\\The IT Crowd (2006)": 9239572772,
"P:\\tv\\Winning Time - The Rise of the Lakers Dynasty (2022)": 37911197652,
"P:\\tv\\Monet's Slumber Party": 8253206091,
"P:\\tv\\Walker": 5492500161,
"P:\\tv\\Stargirl": 9507100884,
"P:\\tv\\House of Guinness (2025)": 5444928896,
"P:\\tv\\Father Brown": 18896564477,
"P:\\tv\\Silo (2023)": 12897630564,
"P:\\tv\\Your Honor (2020)": 25879839349,
"P:\\tv\\Welcome to Wrexham": 66664948104,
"P:\\tv\\Royal Pains (2009)": 1247586112,
"P:\\tv\\The Continental (2023)": 1920206807,
"P:\\tv\\Citadel": 2339699246,
"P:\\tv\\The 10th Kingdom (2000)": 14174589505,
"P:\\tv\\Parlor Room": 12022280605,
"P:\\tv\\Its Always Sunny in Philadelphia": 84650830434,
"P:\\tv\\Star Wars - Skeleton Crew (2024)": 2940779001,
"P:\\tv\\Rupaul's Drag Race": 59664530796,
"P:\\tv\\Only Murders in the Building (2021)": 2379838148,
"P:\\tv\\Running Man": 10279755878,
"P:\\tv\\Shetland": 18537045340,
"P:\\tv\\Adults (2025)": 6845585714,
"P:\\tv\\iCarly (2021)": 19966043984,
"P:\\tv\\Villainous (2017)": 1961793524,
"P:\\tv\\The Terminal List - Dark Wolf (2025)": 9939046560,
"P:\\tv\\Ted Lasso (2020)": 52046307136,
"P:\\tv\\Murderbot (2025)": 18338040970,
"P:\\tv\\RuPaul's Drag Race Down Under": 27454793482,
"P:\\tv\\Gravity Falls": 31900305156,
"P:\\tv\\The Santa Clauses (2022)": 6400385164,
"P:\\tv\\Marvel's The Punisher (2017)": 32242478897,
"P:\\tv\\Dracula (2020)": 2147285239,
"P:\\tv\\Extraordinary": 6934203888,
"P:\\tv\\Cyberpunk - Edgerunners (2022)": 11313875182,
"P:\\tv\\Rick and Morty": 31672318625,
"P:\\tv\\Welcome to Chippendales (2022)": 10423545837,
"P:\\tv\\Squid Game (2021)": 22082475135,
"P:\\tv\\MobLand (2025)": 6622179548,
"P:\\tv\\Taskmaster (NZ)": 71323320898,
"P:\\tv\\The Newsroom": 27756667258,
"P:\\tv\\The Pretender": 18425629462,
"P:\\tv\\Hazbin Hotel (2024)": 10906489515,
"P:\\tv\\Raised by wolves": 9720677524,
"P:\\tv\\Tomb Raider - The Legend of Lara Croft": 9341088252,
"P:\\tv\\Spartacus": 75639017886,
"P:\\tv\\Worst Cooks in America (2010)": 27887501056,
"P:\\tv\\Avenue 5": 12572813494,
"P:\\tv\\Man Down (2013)": 5077144151,
"P:\\tv\\Outlander": 27364180668,
"P:\\tv\\The Eternaut": 17178505929,
"P:\\tv\\Below Deck Down Under (2022)": 36006759742,
"P:\\tv\\Dirty Laundry": 27626331672,
"P:\\tv\\Chilling Adventures of Sabrina (2018)": 23147355371,
"P:\\tv\\The Studio (2025)": 11530554023,
"P:\\tv\\The Forsytes (2025)": 4034792830,
"P:\\tv\\Platonic (2023)": 17488146510,
"P:\\tv\\Love Island (US) (2019)": 20699120877,
"P:\\tv\\Dark Side of the Ring": 11863132534,
"P:\\tv\\The Day of the Jackal (2024)": 17787097381,
"P:\\tv\\Utopia (AU)": 8691287022,
"P:\\tv\\Sweetpea": 2706241673,
"P:\\tv\\Dateline NBC (1992)": 19267231607,
"P:\\tv\\Euphoria": 40925172559,
"P:\\tv\\The Consultant (2023)": 74,
"P:\\tv\\Titans (2018)": 31986198137,
"P:\\tv\\Taskmaster": 142193364333,
"P:\\tv\\Ink Master": 23329086486,
"P:\\tv\\Dimension 20": 559394428110,
"P:\\tv\\Continuum (2012)": 29352883496,
"P:\\tv\\South Park": 70261225261,
"P:\\tv\\Letterkenny": 63,
"P:\\tv\\Ghosts (2019)": 40703143881,
"P:\\tv\\Moon Knight": 10976093361,
"P:\\tv\\Twisted Metal (2023)": 12547412897,
"P:\\tv\\Extrapolations": 6690715385,
"P:\\tv\\Quiet On Set - The Dark Side Of Kids TV": 12191520028,
"P:\\tv\\Sh\u014dgun": 20899988683,
"P:\\tv\\Taboo (2017)": 19309841226,
"P:\\tv\\Ironheart (2025)": 3153557870,
"P:\\tv\\DOTA - Dragon's Blood (2021)": 12538510766,
"P:\\tv\\Knuckles": 2140786440,
"P:\\tv\\Shoresy": 10192565178,
"P:\\tv\\Impractical Jokers": 13357380400,
"P:\\tv\\One More Time (2024)": 6434473461,
"P:\\tv\\Crowd Control": 9644641207,
"P:\\tv\\Dimension 20's Adventuring Party": 12563974792,
"P:\\tv\\Special Ops Lioness": 9765393961,
"P:\\tv\\Ted (2024)": 3024624414,
"P:\\tv\\Mighty Nein (2025)": 6138965943,
"P:\\tv\\Citadel - Diana": 13304679453,
"P:\\tv\\Our Flag Means Death": 2107045664,
"P:\\tv\\Make Some Noise": 26524123873,
"P:\\tv\\Mayor of Kingstown (2021)": 65464041666,
"P:\\tv\\The Take": 6020370013,
"P:\\tv\\Agatha All Along": 3411637969,
"P:\\tv\\The Amazing Digital Circus (2023)": 4739070191,
"P:\\tv\\The Now": 836886747,
"P:\\tv\\Poppa\u2019s House": 13794748297,
"P:\\tv\\Married at First Sight (2014)": 30275711911,
"P:\\tv\\The Closer": 47449608535,
"P:\\tv\\Junior Taskmaster (2024)": 4133620030,
"P:\\tv\\WondLa": 1399628000,
"P:\\tv\\The Second Best Hospital in the Galaxy (2024)": 3636394169,
"P:\\tv\\Being Human (2011)": 66311454464,
"P:\\tv\\SCORPION": 54081802764,
"P:\\tv\\The Goes Wrong Show (2019)": 3676343887,
"P:\\tv\\See": 12316511887,
"P:\\tv\\Dirk Gently's Holistic Detective Agency (2016)": 11935610182,
"P:\\tv\\Tokyo Override (2024)": 3802255332,
"P:\\tv\\Peacemaker (2022)": 13199970800,
"P:\\tv\\The Falcon and The Winter Soldier (2021)": 11657055937,
"P:\\tv\\Fargo (2014)": 93247402537,
"P:\\tv\\Killer Cakes": 3673781461,
"P:\\tv\\The Mandalorian": 36487773789,
"P:\\tv\\Very Important People": 14563355278,
"P:\\tv\\Smiling Friends": 5633340834,
"P:\\tv\\Game Changers (2024)": 5880504271,
"P:\\tv\\Star Strek Strange New Worlds": 13781151928,
"P:\\tv\\Galavant": 12147863291,
"P:\\tv\\She-Hulk Attorney at Law": 10233633417,
"P:\\tv\\From Dusk Till Dawn - The Series (2014)": 5360771338,
"P:\\tv\\The Journal of the Mysterious Creatures (2019)": 92,
"P:\\tv\\Fallen (2024)": 4161867429,
"P:\\tv\\Severance": 15044806873,
"P:\\tv\\The Great (2020)": 22361386693,
"P:\\tv\\What If": 21312022582,
"P:\\tv\\Rupaul's Drag Race UK": 110914388896,
"P:\\tv\\Game Of Thrones": 119681469870,
"P:\\tv\\Belgravia - The Next Chapter": 8340040939,
"P:\\tv\\Hitmen (2020)": 12274410846,
"P:\\tv\\Haunted Hotel (2025)": 4735071992,
"P:\\tv\\The Book of Boba Fett": 12039417291,
"P:\\tv\\SAS Rogue Heroes (2022)": 10733559643,
"P:\\tv\\Dwight in Shining Armor": 75,
"P:\\tv\\Jury Duty": 8010062372,
"P:\\tv\\Son of Zorn (2016)": 6780978712,
"P:\\tv\\The Gentlemen (2024)": 5224500371,
"P:\\tv\\Schmigadoon!": 6206632733,
"P:\\tv\\The Drew Carey Show (1995)": 70,
"P:\\tv\\Fired on Mars (2023)": 3590992124,
"P:\\tv\\Black Bird (2022)": 5893929480,
"P:\\tv\\Billions": 31141419259,
"P:\\tv\\Reacher (2022)": 17521873037,
"P:\\tv\\The Morning Show": 94311701751,
"P:\\tv\\Secret Level": 2810124465,
"P:\\tv\\The Boys": 68010010167,
"P:\\tv\\Gordon Ramsay's Food Stars (2023)": 6344621632,
"P:\\tv\\Death and Other Details": 17844763765,
"P:\\tv\\Modern Family": 82788065200,
"P:\\tv\\Married... with Children (1987)": 64228823786,
"P:\\tv\\BattleBots": 61,
"P:\\tv\\Silicon Valley (2014)": 63657428121,
"P:\\tv\\Tires (2024)": 5375794389,
"P:\\tv\\Creature Commandos (2024)": 2331424358,
"P:\\tv\\Goosebumps (2023)": 8257419062,
"P:\\tv\\The Fall of the House of Usher (2023)": 16454192941,
"P:\\tv\\Passion for punchlines": 75514795,
"P:\\tv\\The Queen's Gambit": 4100494817,
"P:\\tv\\Suits LA (2025)": 22274831381,
"P:\\tv\\Dune - Prophecy": 3330003290,
"P:\\tv\\Unstable": 5444623642,
"P:\\tv\\The Split": 7970767632,
"P:\\tv\\Barry": 31934844666,
"P:\\tv\\The Dragon Dentist": 11317084093,
"P:\\tv\\Kevin Can F-k Himself": 11614889793
} }

422
ARCHITECTURE.md Normal file
View File

@ -0,0 +1,422 @@
# Interactive Audio Stream Selection - Architecture Diagram
## System Architecture
```
┌─────────────────────────────────────────────────────────────────┐
│ main.py │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ ArgumentParser │ │
│ │ --filter-audio (enables audio filtering) │ │
│ │ --interactive (enables interactive mode) ← NEW │ │
│ │ --cq, --r, --m, --language, --test (existing) │ │
│ └──────────────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ normalize_input_path() → folder path │ │
│ └──────────────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ process_folder( │ │
│ │ filter_audio=True/False, │ │
│ │ interactive_audio=True/False ← NEW │ │
│ │ ) │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ core/process_manager.py │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ process_folder(folder, ..., filter_audio, interactive) │ │
│ │ ↑ NEW param │ │
│ └──────────────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ For each video file: │ │
│ │ 1. Get source resolution & target resolution │ │
│ │ 2. Create audio_filter_config dict: │ │
│ │ { │ │
│ │ "enabled": filter_audio, │ │
│ │ "interactive": interactive_audio ← NEW FIELD │ │
│ │ } │ │
│ │ 3. Call run_ffmpeg() with audio_filter_config │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ core/encode_engine.py │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ run_ffmpeg( │ │
│ │ input_file, output_file, ..., │ │
│ │ audio_filter_config={enabled, interactive} │ │
│ │ ) │ │
│ └──────────────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 1. streams = get_audio_streams(input_file) │ │
│ │ └─ Returns: [(index, ch, br, lang, meta), ...] │ │
│ │ │ │
│ │ 2. if audio_filter_config.get("enabled"): │ │
│ │ ├─ if audio_filter_config.get("interactive"): │ │
│ │ │ └─ Call: prompt_user_audio_selection(streams) ← ◆ │ │
│ │ │ [SHOWS PROMPT TO USER] │ │
│ │ │ └─ Returns: filtered_streams │ │
│ │ │ │ │
│ │ └─ else: │ │
│ │ └─ Call: filter_audio_streams(input_file, streams) │ │
│ │ (Automatic: keep best English + Commentary) │ │
│ │ └─ Returns: filtered_streams │ │
│ │ │ │
│ │ 3. For each stream in filtered_streams: │ │
│ │ ├─ choose_audio_bitrate() (codec selection) │ │
│ │ └─ Build FFmpeg codec params (-c:a, -b:a, etc.) │ │
│ │ │ │
│ │ 4. subprocess.run(ffmpeg_cmd) │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ core/audio_handler.py │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ def prompt_user_audio_selection(streams) ← NEW FUNCTION │ │
│ │ ◆ Interactive User Prompt ◆ │ │
│ │ │ │
│ │ Display: │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ 🎵 AUDIO STREAM SELECTION │ │ │
│ │ │ │ │ │
│ │ │ Stream #0: 2ch | Lang: eng | Bitrate: 128kbps │ │
│ │ │ Stream #1: 6ch | Lang: eng | Bitrate: 448kbps │ │
│ │ │ Stream #2: 2ch | Lang: spa | Bitrate: 128kbps │ │
│ │ │ Stream #3: 2ch | Lang: comment | Bitrate: 64kbps │ │
│ │ │ │ │ │
│ │ │ Keep streams: 1,3 │ │ │
│ │ │ │ │ │
│ │ │ ✅ Keeping 2 stream(s), removing 2 stream(s) │ │
│ │ └──────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ Process: │ │
│ │ 1. Check if streams empty/single → return as-is │ │
│ │ 2. Display all streams with formatting │ │
│ │ 3. Prompt user for comma-separated indices │ │
│ │ 4. Parse and validate input │ │
│ │ 5. Filter streams to selected only │ │
│ │ 6. Log selections & removed streams │ │
│ │ 7. Return filtered_streams │ │
│ │ │ │
│ │ Error Handling: │ │
│ │ • Invalid input → Keep all (log warning) │ │
│ │ • No selections → Keep all (log warning) │ │
│ │ • Empty input → Keep all (user confirmed) │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
```
## Data Flow Example
### User Command
```bash
python main.py "C:\Videos" --filter-audio --interactive
```
### Data Transformation
```
Step 1: ArgumentParser
─────────────────────
Input Args:
folder = "C:\Videos"
filter_audio = True
interactive_audio = True
Output: args object
────────────────────────────────────────────────────────
Step 2: main() → process_folder()
───────────────────────────────────
Input:
folder, filter_audio=True, interactive_audio=True
Output: Called with both flags
────────────────────────────────────────────────────────
Step 3: process_folder() → Builds audio_filter_config
──────────────────────────────────────────────────────
Input:
filter_audio=True
interactive_audio=True
Logic:
if filter_audio is not None:
audio_filter_config = {
"enabled": True,
"interactive": True ← NEW
}
Output: audio_filter_config dict
────────────────────────────────────────────────────────
Step 4: process_folder() → run_ffmpeg()
─────────────────────────────────────────
Input:
input_file = "movie.mkv"
audio_filter_config = {"enabled": True, "interactive": True}
Output: Called with config
────────────────────────────────────────────────────────
Step 5: run_ffmpeg() → Audio Stream Detection
──────────────────────────────────────────────
Input:
input_file = "movie.mkv"
Output:
streams = [
(0, 2, 128, "eng", 0), # Stream #0: 2ch English 128kbps
(1, 6, 448, "eng", 0), # Stream #1: 6ch English 448kbps
(2, 2, 128, "spa", 0), # Stream #2: 2ch Spanish 128kbps
(3, 2, 64, "und", 0) # Stream #3: 2ch Undefined 64kbps
]
────────────────────────────────────────────────────────
Step 6: Audio Filtering Decision
────────────────────────────────
Input:
audio_filter_config = {"enabled": True, "interactive": True}
streams = [4 streams above]
Logic:
if audio_filter_config.get("enabled"): ✓ True
if audio_filter_config.get("interactive"): ✓ True
→ Call prompt_user_audio_selection() ← INTERACTIVE PATH
Output: User prompt shown to console
────────────────────────────────────────────────────────
Step 7: prompt_user_audio_selection() → User Input
──────────────────────────────────────────────────────
Input:
streams = [4 streams]
Display:
🎵 AUDIO STREAM SELECTION
════════════════════════════════════════════════════
Stream #0: 2ch | Lang: eng | Bitrate: 128kbps
Stream #1: 6ch | Lang: eng | Bitrate: 448kbps
Stream #2: 2ch | Lang: spa | Bitrate: 128kbps
Stream #3: 2ch | Lang: undefined | Bitrate: 64kbps
Keep streams: ← WAIT FOR USER INPUT
User Input:
"1,3"
Parse:
selected_indices = {1, 3}
Filter:
filtered = [
(1, 6, 448, "eng", 0), ✓ Keep
(3, 2, 64, "und", 0) ✓ Keep
]
Output:
✅ Keeping 2 stream(s), removing 2 stream(s)
Return: filtered streams
────────────────────────────────────────────────────────
Step 8: Back to run_ffmpeg() → Codec Selection
──────────────────────────────────────────────
Input:
streams = [
(1, 6, 448, "eng", 0),
(3, 2, 64, "und", 0)
]
Process each stream:
Stream 1: 6ch → choose_audio_bitrate() → ("eac3", 384000)
Stream 3: 2ch → choose_audio_bitrate() → ("aac", 160000)
Output:
FFmpeg codec params:
-c:a:1 eac3 -b:a:1 384k -ac:1 6 -channel_layout:1 5.1
-c:a:3 aac -b:a:3 160k -ac:3 2 -channel_layout:3 stereo
────────────────────────────────────────────────────────
Step 9: FFmpeg Encoding
───────────────────────
Input:
ffmpeg -i movie.mkv \
-vf scale=... \
-c:v av1_nvenc \
-c:a:1 eac3 -b:a:1 384k ... \
-c:a:3 aac -b:a:3 160k ... \
output.mkv
Process:
FFmpeg encodes video and audio streams
Only streams 1 and 3 included (streams 0 and 2 excluded)
Output:
output.mkv (with only selected audio tracks)
```
## State Diagram
```
┌─────────────────────────────────┐
│ User Runs Script │
│ --filter-audio --interactive │
└──────────────┬──────────────────┘
┌─────────────────────────────────┐
│ Parse Arguments │
│ interactive_audio = True │
└──────────────┬──────────────────┘
┌─────────────────────────────────┐
│ process_folder() │
│ Build audio_filter_config │
│ {enabled: T, interactive: T} │
└──────────────┬──────────────────┘
┌────────────┴────────────┐
│ │
▼ ▼
For each file Detect audio streams
┌──────────────┐ get_audio_streams()
│ run_ffmpeg() │ └─ Returns 4 streams
└──────┬───────┘
┌──────────────────────────┐
│ Check filter enabled? │
│ audio_filter_config │
└──────┬─────────────┬─────┘
│ No │ Yes
│ ▼
│ ┌─────────────────────┐
│ │ Check interactive? │
│ └────┬────────────┬───┘
│ │ No │ Yes
│ │ ▼
│ │ ┌───────────────────┐
│ │ │ INTERACTIVE PROMPT│
│ │ │ Show streams │
│ │ │ Get user input │
│ │ │ Filter streams │
│ │ └─────────┬─────────┘
│ │ │
│ ▼ │
│ ┌──────────────────┐ │
│ │ Automatic Filter │ │
│ │ (Best English + │ │
│ │ Commentary) │ │
│ └─────────┬────────┘ │
│ │ │
└────────────────┴───────────┘
┌────────────────────────────────┐
│ Apply Codec Selection │
│ (for selected streams only) │
│ choose_audio_bitrate() │
└────────────┬───────────────────┘
┌────────────────────────────────┐
│ Build FFmpeg Command │
│ (with selected audio streams) │
└────────────┬───────────────────┘
┌────────────────────────────────┐
│ Run FFmpeg Encoding │
│ subprocess.run(cmd) │
└────────────┬───────────────────┘
┌────────────────────────────────┐
│ Success/Failure Handling │
│ Log Results │
└────────────┬───────────────────┘
┌────────────┴─────────┐
│ │
Next file? Process Complete
```
## Component Interaction
```
┌─────────────┐
│ main.py │
└──────┬──────┘
│ calls with (filter_audio, interactive_audio)
┌──────────────────────┐
│ process_manager.py │
├──────────────────────┤
│ • Build config │ ◄─── Set "interactive" field
│ • For each file: │ in audio_filter_config
│ └─ run_ffmpeg() │
└──────┬───────────────┘
│ passes audio_filter_config
┌──────────────────────┐
│ encode_engine.py │
├──────────────────────┤
│ • Check "enabled" │ ◄─── Decide which
│ • Check "interactive"│ filtering method
│ • Route to: │ to use
│ ├─ interactive path│
│ └─ automatic path │
└──────┬───────────────┘
│ passes streams
┌──────────────────────┐
│ audio_handler.py │
├──────────────────────┤
│ • Interactive: │
│ prompt_user_...() │◄──── NEW FUNCTION
│ └─ Show & filter │ Shows prompt
│ │ Gets user input
│ • Automatic: │ Returns filtered
│ filter_audio_...() │
│ └─ Logic filter │
└──────────────────────┘
│ returns filtered streams
┌──────────────────────┐
│ encode_engine.py │
├──────────────────────┤
│ • Codec selection │
│ • Build FFmpeg cmd │
│ • Run encoding │
└──────────────────────┘
```
---
This architecture ensures clean separation of concerns:
- **main.py**: CLI interface
- **process_manager.py**: Orchestration & config building
- **encode_engine.py**: FFmpeg command building & execution
- **audio_handler.py**: Audio detection & stream filtering
The interactive prompt is cleanly isolated in `audio_handler.py` and only called when needed.

81
ENCODER_SWITCH.md Normal file
View File

@ -0,0 +1,81 @@
# Dual Encoder Support - Implementation Complete ✅
## Features Added
The transcoder now supports switching between two video encoders via the `--encoder` CLI option:
### 1. **HEVC NVENC 10-bit** (Default)
- **Command**: `--encoder nvenc` or default (no flag needed)
- **Codec**: `hevc_nvenc`
- **Preset**: `slow` (high quality)
- **Bit Depth**: 10-bit
- **Pixel Format**: `yuv420p10le`
- **Use Case**: Best quality archival format, suitable for Plex compatibility
### 2. **AV1 NVENC 8-bit**
- **Command**: `--encoder av1`
- **Codec**: `av1_nvenc`
- **Preset**: `p7` (high quality)
- **Bit Depth**: 8-bit
- **Pixel Format**: `yuv420p`
- **Use Case**: Maximum file size reduction, modern playback devices
## Usage Examples
```bash
# Default to HEVC NVENC 10-bit with smart resolution scaling
python main.py "C:\Videos\Movies"
# Force AV1 NVENC 8-bit encoding
python main.py "C:\Videos\TV" --encoder av1
# AV1 with explicit resolution
python main.py "C:\Videos\Anime" --encoder av1 --r 1080
# AV1 with CQ mode at specific quality
python main.py "C:\Videos\Low-Res" --encoder av1 --cq 28
# AV1 with bitrate mode
python main.py "C:\Videos\Movies" --encoder av1 --m bitrate
# HEVC (explicit, though it's the default)
python main.py "C:\Videos\TV" --encoder nvenc --cq 26
```
## Configuration
Encoder settings are stored in `config.xml`:
```xml
<encoder default="nvenc">
<av1_nvenc preset="p7" bit_depth="8" pix_fmt="yuv420p" />
<hevc_nvenc preset="slow" bit_depth="10" pix_fmt="yuv420p10le" />
</encoder>
```
The `default="nvenc"` attribute can be changed, but CLI `--encoder` flag always takes precedence.
## Files Modified
1. **config.xml** - Added `<encoder>` section with both encoder configurations
2. **main.py** - Added `--encoder` argument, defaults to "nvenc"
3. **encode_engine.py** - Updated `run_ffmpeg()` to:
- Accept `encoder` parameter
- Dynamically set encoder codec, preset, bit depth, and pixel format
- Display encoder details in logging output
4. **process_manager.py** - Updated to:
- Accept and pass `encoder` parameter through processing pipeline
- Updated both Phase 1 (initial encode) and Phase 2 (bitrate retry) encode calls
## Quality Notes
| Aspect | HEVC NVENC | AV1 NVENC |
|--------|-----------|----------|
| **File Size** | ~80-90% of AV1 | Smallest (baseline) |
| **Quality** | Excellent | Excellent |
| **Preset** | slow (p6) | p7 |
| **Bit Depth** | 10-bit | 8-bit |
| **Compatibility** | Excellent (Plex) | Good (modern devices) |
| **Encoding Speed** | Fast | Fast |
Both encoders use NVIDIA GPU acceleration (NVENC) for fast encoding.

280
IMPLEMENTATION_COMPLETE.md Normal file
View File

@ -0,0 +1,280 @@
# Interactive Audio Stream Selection - Complete Implementation
## Overview
**COMPLETE** - Interactive audio stream selection feature has been successfully implemented.
Users can now view all available audio streams in each video file and select which ones to keep for encoding, providing fine-grained control over audio track inclusion.
## Features Implemented
### 1. Stream Display ✅
- Shows all audio streams with human-readable format
- Displays: Stream number, channel count, language code, bitrate
- Clear visual separation and organized layout
- Example: `Stream #0: 2ch | Lang: eng | Bitrate: 128kbps`
### 2. User Input ✅
- Accepts comma-separated stream indices: `0,1,3`
- Accepts single stream: `1`
- Accepts blank input (keep all streams)
- Input validation with helpful error messages
- Optional spaces in comma-separated list: `0, 1, 3`
### 3. Filtering ✅
- Removes non-selected streams from encoding
- Preserves original stream indices for FFmpeg mapping
- Logs all selections and removals
- Falls back to keeping all streams on invalid input
### 4. CLI Integration ✅
- New flag: `--interactive` (boolean)
- Works with `--filter-audio` flag
- Can be used independently (auto-enables filtering)
- Integrated into argument parser with help text
### 5. Processing Pipeline ✅
- Called from `run_ffmpeg()` in encode_engine.py
- Executed after stream detection
- Executed before codec selection
- Per-file prompting (allows different selections per video)
### 6. Logging ✅
- Logs user selections: `User selected X audio stream(s): [0, 1, 3]`
- Logs removed streams: `Removed X audio stream(s): [2]`
- Logs invalid input attempts
- Integrated with project's logging system
## File Changes Summary
### main.py
**Added**:
- `--interactive` argument to argparse
- Pass `args.interactive_audio` to `process_folder()`
**Lines Changed**: 2
### core/process_manager.py
**Added**:
- `interactive_audio: bool = False` parameter to function signature
- Logic to set `audio_filter_config["interactive"]` based on CLI args
- Auto-enable filtering if `--interactive` used without `--filter-audio`
**Lines Changed**: ~5
### core/encode_engine.py
**Added**:
- Import `prompt_user_audio_selection`
- Check for `audio_filter_config.get("interactive", False)`
- Route to interactive or automatic filtering accordingly
**Lines Changed**: ~5
### core/audio_handler.py
**Added**:
- `prompt_user_audio_selection()` function (64 lines)
- Comprehensive docstring
- User-friendly output formatting
- Input validation and error handling
- Logging integration
**Lines Changed**: +64 (new function)
## Code Structure
### Function: `prompt_user_audio_selection(streams: list) -> list`
**Location**: `core/audio_handler.py` (line 297)
**Parameters**:
- `streams`: List of (index, channels, bitrate, language, metadata) tuples
**Returns**:
- Filtered list containing only user-selected streams
**Key Features**:
1. Early return if 0-1 streams (no selection needed)
2. Display header with visual formatting
3. Show each stream with index, channels, language, bitrate
4. Prompt for user input with examples
5. Parse comma-separated input
6. Validate stream indices
7. Handle edge cases (empty input, invalid input)
8. Log results to project logger
9. Return filtered streams ready for encoding
**Error Handling**:
- ValueError on unparseable input → keep all
- No valid selections → keep all with warning
- Empty input → keep all (user confirmed)
## Execution Flow
```
User runs:
$ python main.py "C:\Videos" --filter-audio --interactive
main.py parses arguments
- filter_audio = True (from --filter-audio)
- interactive_audio = True (from --interactive)
process_folder() called with both flags
For each video file:
└─ run_ffmpeg() called
└─ get_audio_streams() detects streams
└─ Check audio_filter_config.enabled
└─ True: Apply filtering
└─ Check audio_filter_config.interactive
└─ True: Call prompt_user_audio_selection()
└─ [INTERACTIVE PROMPT APPEARS]
└─ User sees streams and selects
└─ Returns filtered stream list
└─ False: Call filter_audio_streams()
└─ Automatic filtering (keep best English + Commentary)
└─ Process selected streams for encoding
```
## Usage Examples
### Basic Interactive Mode
```bash
python main.py "C:\Videos\Movies" --filter-audio --interactive
```
### Combined with Other Options
```bash
python main.py "C:\Videos\TV" --filter-audio --interactive --cq 28 --r 1080 --language eng
```
### Interactive Without Explicit --filter-audio
```bash
python main.py "C:\Videos\Anime" --interactive
```
(Filtering is auto-enabled with interactive mode)
## Testing Scenarios
### Scenario 1: Multiple Audio Languages
**Input**: Video with English (stereo), English (5.1), Spanish, Commentary
**Expected**: Prompt shows 4 streams, user can select any combination
### Scenario 2: Invalid Selection
**Input**: User types "abc" or non-existent stream number
**Expected**: Tool logs warning, keeps all streams, continues
### Scenario 3: Single Audio Stream
**Input**: Video with only one audio track
**Expected**: Function returns early, no prompt shown
### Scenario 4: Empty Input
**Input**: User presses Enter without typing
**Expected**: All streams kept, confirmation message shown
## Backward Compatibility
✅ **Fully Backward Compatible**
- Existing `--filter-audio` behavior unchanged
- New feature is opt-in via `--interactive` flag
- Default behavior (no interactive) preserved
- No changes to config.xml schema required
- All existing scripts/automation continues to work
## Integration Points
### With Audio Language Tagging
- `--language eng --filter-audio --interactive` works together
- User selects streams, then language metadata applied to all
### With Resolution/CQ Options
- `--filter-audio --interactive --cq 28 --r 1080` fully compatible
- Interactive selection happens first, encoding follows
### With Test Mode
- `--filter-audio --interactive --test` shows interactive prompt on first file
- Useful for testing selections before batch encoding
## Performance Impact
✅ **Minimal Impact**
- Interactive prompt only appears when user explicitly requests it
- No performance overhead when `--interactive` not used
- Per-file prompt adds negligible time (user wait for input)
- No change to FFmpeg encoding performance
## Documentation Provided
1. **INTERACTIVE_AUDIO.md** - User guide with examples
2. **IMPLEMENTATION_NOTES.md** - Technical implementation details
3. **QUICK_REFERENCE.md** - Quick reference guide and FAQ
4. This summary document
## Completion Checklist
✅ Function implementation (prompt_user_audio_selection)
✅ CLI argument (--interactive)
✅ Integration with process_manager
✅ Integration with encode_engine
✅ Input validation
✅ Error handling
✅ Logging integration
✅ Backward compatibility
✅ Documentation
✅ Syntax validation
✅ Code review
## Example Output
When user runs with `--filter-audio --interactive`:
```
================================================================================
🎵 AUDIO STREAM SELECTION
================================================================================
Stream #0: 2ch | Lang: eng | Bitrate: 128kbps
Stream #1: 6ch | Lang: eng | Bitrate: 448kbps
Stream #2: 2ch | Lang: spa | Bitrate: 128kbps
Stream #3: 2ch | Lang: comment | Bitrate: 64kbps
────────────────────────────────────────────────────────────────────────────
Enter stream numbers to keep (comma-separated, e.g.: 1,2 or just 2)
Leave blank to keep all streams
────────────────────────────────────────────────────────────────────────────
➜ Keep streams: 1,3
✅ Keeping 2 stream(s), removing 2 stream(s)
🎬 Running CQ encode: output.mkv
...
```
## Next Steps (Optional Enhancements)
Future improvements could include:
- [ ] Preset buttons for common selections (e.g., "Best Audio", "English Only", "All")
- [ ] Auto-numbering display for clarity
- [ ] Arrow key selection interface (more interactive)
- [ ] Save/load selection templates for batch consistency
- [ ] GUI interface for stream selection
- [ ] Default selection from config for silent/batch operation
---
## Summary
The interactive audio stream selection feature is **complete and ready for use**. Users can now:
1. ✅ See all available audio streams with details
2. ✅ Choose which streams to keep for encoding
3. ✅ Get immediate confirmation of their selection
4. ✅ Have per-file control in batch operations
5. ✅ Maintain automatic fallback if input is invalid
The implementation is clean, well-documented, backward-compatible, and fully integrated into the existing codebase.

141
IMPLEMENTATION_NOTES.md Normal file
View File

@ -0,0 +1,141 @@
# Interactive Audio Stream Selection - Implementation Summary
## Changes Made
### 1. New Function: `prompt_user_audio_selection()` in audio_handler.py
- **Purpose**: Display audio streams and prompt user for selection
- **Input**: List of streams with (index, channels, bitrate, language, metadata)
- **Output**: Filtered list containing only user-selected streams
- **Features**:
- Displays stream info: `Stream #X: YYch | Lang: YYY | Bitrate: XYZkbps`
- Accepts comma-separated input: `1,2,3` or `1` or empty (keep all)
- Validates input and logs selections
- Falls back to keeping all streams on invalid input
### 2. Updated: `run_ffmpeg()` in encode_engine.py
- Now checks `audio_filter_config.get("interactive", False)`
- Routes to interactive prompt if `interactive=True`
- Routes to automatic filtering if `interactive=False`
- Both modes filter streams before codec selection
### 3. Updated: `process_folder()` in process_manager.py
- New parameter: `interactive_audio: bool = False`
- Builds audio_filter_config with both `enabled` and `interactive` fields
- If `--interactive` used without `--filter-audio`, enables both automatically
### 4. Updated: main.py
- New CLI argument: `--interactive`
- Action: `store_true` (binary flag)
- Passed through to `process_folder()`
- Help text: "Interactive mode: show audio streams and let user select which to keep (requires --filter-audio)"
## Usage Examples
### Example 1: Automatic Filtering (Existing)
```bash
python main.py "C:\Videos" --filter-audio
```
- Automatically keeps best English + Commentary
- No user interaction
### Example 2: Interactive Selection (New)
```bash
python main.py "C:\Videos" --filter-audio --interactive
```
- Shows each file's audio streams
- User picks which streams to keep
- Different selections per file allowed
### Example 3: Interactive Without --filter-audio
```bash
python main.py "C:\Videos" --interactive
```
- Same as Example 2 (enables filtering automatically)
- More intuitive UX
## Stream Display Format
When interactive mode runs, user sees:
```
================================================================================
🎵 AUDIO STREAM SELECTION
================================================================================
Stream #0: 2ch | Lang: eng | Bitrate: 128kbps
Stream #1: 6ch | Lang: eng | Bitrate: 448kbps
Stream #2: 2ch | Lang: spa | Bitrate: 128kbps
────────────────────────────────────────────────────────────────────────────
Enter stream numbers to keep (comma-separated, e.g.: 1,2 or just 2)
Leave blank to keep all streams
────────────────────────────────────────────────────────────────────────────
➜ Keep streams:
```
## Logging Output
When user selects streams:
```
✅ Keeping 2 stream(s), removing 1 stream(s)
User selected 2 audio stream(s): [1, 2]
Removed 1 audio stream(s): [0]
```
## Audio Filter Config Structure
**Old (Automatic only)**:
```python
{
"enabled": True/False
}
```
**New (With Interactive)**:
```python
{
"enabled": True/False,
"interactive": True/False
}
```
## Flow Diagram
```
main.py
└─ parse args (--filter-audio, --interactive)
└─ process_folder()
└─ for each file:
└─ run_ffmpeg()
└─ get_audio_streams()
└─ if audio_filter_config.enabled:
├─ if audio_filter_config.interactive:
│ └─ prompt_user_audio_selection() ← NEW
│ └─ [User sees streams and selects]
└─ else:
└─ filter_audio_streams() (automatic)
└─ encode with selected streams
```
## Input Validation
- **Valid**: `1`, `0,1,3`, `2, 3, 5` (spaces OK)
- **Invalid**: `abc`, `1.5`, `1-3` (ranges not supported)
- **On Invalid**: Keep all streams, log warning
## Edge Cases Handled
1. **No streams**: Return original (nothing to filter)
2. **Single stream**: Return as-is (no selection needed)
3. **Invalid stream indices**: Keep all streams
4. **Empty input**: Keep all streams
5. **No valid selections**: Keep all streams (with warning)
## Backward Compatibility
- Existing `--filter-audio` behavior unchanged (automatic mode)
- `--interactive` is optional, defaults to False
- No breaking changes to config.xml structure
- Language tagging (--language) still works alongside audio filtering

109
INTERACTIVE_AUDIO.md Normal file
View File

@ -0,0 +1,109 @@
# Interactive Audio Stream Selection
## Overview
The conversion tool now supports **interactive audio stream selection**, allowing you to manually choose which audio tracks to keep during encoding rather than relying on automatic filtering.
## Usage
### Enable Interactive Mode
Use both `--filter-audio` and `--interactive` flags together:
```bash
python main.py "C:\path\to\videos" --filter-audio --interactive
```
### What Happens
When encoding each file with multiple audio streams:
1. **Audio Stream Display**
- The tool displays all available audio streams with details:
```
🎵 AUDIO STREAM SELECTION
================================================================================
Stream #0: 2ch | Lang: eng | Bitrate: 128kbps
Stream #1: 6ch | Lang: eng | Bitrate: 448kbps
Stream #2: 2ch | Lang: spa | Bitrate: 128kbps
Stream #3: 2ch | Lang: comment | Bitrate: 64kbps
```
2. **User Prompt**
- You're asked to select which streams to keep:
```
────────────────────────────────────────────────────────────────────────────
Enter stream numbers to keep (comma-separated, e.g.: 1,2 or just 2)
Leave blank to keep all streams
────────────────────────────────────────────────────────────────────────────
➜ Keep streams: 1,3
```
3. **Encoding
**
- Only selected streams are included in the encoded output
- Other streams are removed
- Selection is logged for reference
## Input Format
- **Multiple streams**: `0,1,3` or `0, 1, 3` (spaces optional)
- **Single stream**: `1` or `2`
- **Keep all**: Press Enter without typing anything
## Example Scenarios
### Scenario 1: Keep Main Audio Only
```
Streams:
Stream #0: 2ch (English, 128kbps)
Stream #1: 6ch (English Surround, 448kbps) ← Best quality
Stream #2: 2ch (Spanish, 128kbps)
Input: 1
Result: Only Stream #1 (6ch English Surround) is encoded
```
### Scenario 2: Keep Multiple Languages
```
Streams:
Stream #0: 2ch (English, 128kbps)
Stream #1: 6ch (English Surround, 448kbps)
Stream #2: 2ch (Spanish, 128kbps)
Stream #3: 2ch (Commentary, 64kbps)
Input: 1,2,3
Result: Streams #1, #2, and #3 are encoded (English Surround, Spanish, Commentary)
```
## Comparison with Automatic Filtering
### Automatic Mode (--filter-audio only)
- Keeps: Best English audio + all Commentary tracks
- No user interaction
- Faster batch processing
### Interactive Mode (--filter-audio --interactive)
- Shows all streams and asks user to choose
- Per-file control
- Better for selective archiving/organization
- Useful when automatic filtering doesn't match your preferences
## Logging
All user selections are logged to the conversion log for reference:
```
User selected 2 audio stream(s): [1, 3]
Removed 1 audio stream(s): [2]
```
## Notes
- Interactive mode requires `--filter-audio` to be enabled
- If you use `--interactive` without `--filter-audio`, filtering is automatically enabled
- Invalid input (non-existent stream numbers) falls back to keeping all streams
- Empty input keeps all audio streams unchanged
- The prompt appears for each file being encoded, allowing different selections per file

View File

@ -1,7 +1,7 @@
# AV1 Batch Video Transcoder - Project Structure # AV1 Batch Video Transcoder - Project Structure
## Overview ## Overview
A modular batch AV1 video transcoding system using NVIDIA's av1_nvenc codec (10-bit p010le) with intelligent audio/video processing, subtitle embedding, and optional audio language tagging. A modular batch AV1 video transcoding system using NVIDIA's av1_nvenc codec (8-bit yuv420p) with intelligent audio/video processing, subtitle embedding, and optional audio language tagging.
## Recent Changes (Latest Session) ## Recent Changes (Latest Session)
@ -64,7 +64,7 @@ A modular batch AV1 video transcoding system using NVIDIA's av1_nvenc codec (10-
#### `core/encode_engine.py` #### `core/encode_engine.py`
- **`run_ffmpeg(input_file, output_file, cq, scale_width, scale_height, src_width, src_height, filter_flags, audio_config, method, bitrate_config, subtitle_file, audio_language)`** - **`run_ffmpeg(input_file, output_file, cq, scale_width, scale_height, src_width, src_height, filter_flags, audio_config, method, bitrate_config, subtitle_file, audio_language)`**
- Builds FFmpeg command with av1_nvenc codec (preset p1, pix_fmt p010le) - Builds FFmpeg command with av1_nvenc codec (preset p7, pix_fmt yuv420p)
- Per-stream audio codec/bitrate decisions - Per-stream audio codec/bitrate decisions
- Conditional subtitle input mapping (if subtitle_file provided) - Conditional subtitle input mapping (if subtitle_file provided)
- Optional audio language metadata (only if audio_language not None) - Optional audio language metadata (only if audio_language not None)

182
QUICK_REFERENCE.md Normal file
View File

@ -0,0 +1,182 @@
# Interactive Audio Selection - Quick Reference
## Command Syntax
### Enable Interactive Audio Selection
```bash
python main.py "C:\path\to\videos" --filter-audio --interactive
```
### Other Flags (Optional)
```bash
--filter-audio --interactive --cq 28 --r 1080 --language eng --test
```
## What User Sees
### Per File Prompt (appears for each video)
```
================================================================================
🎵 AUDIO STREAM SELECTION
================================================================================
Stream #0: 2ch | Lang: eng | Bitrate: 128kbps
Stream #1: 6ch | Lang: eng | Bitrate: 448kbps
Stream #2: 2ch | Lang: spa | Bitrate: 128kbps
Stream #3: 2ch | Lang: comment | Bitrate: 64kbps
────────────────────────────────────────────────────────────────────────────
Enter stream numbers to keep (comma-separated, e.g.: 1,2 or just 2)
Leave blank to keep all streams
────────────────────────────────────────────────────────────────────────────
➜ Keep streams:
```
### User Input Examples
| Input | Result |
|-------|--------|
| `1` | Keep Stream #1 (6ch English, 448kbps) |
| `1,3` | Keep Streams #1 and #3 |
| `0,1,2` | Keep Streams #0, #1, and #2 |
| ` ` (blank) | Keep all 4 streams |
### Expected Output
```
✅ Keeping 1 stream(s), removing 3 stream(s)
🎬 Running CQ encode: output.mkv
...
```
## Features
**Per-File Control**: Different selections for each video
**Clear Display**: See channel count, language, bitrate for each stream
**Flexible Input**: Comma-separated numbers, optional spaces
**Safe Defaults**: Invalid input keeps all streams
**Logging**: All selections recorded in conversion log
**Backwards Compatible**: Doesn't break existing workflows
## Common Scenarios
### Movie with Multiple Audio Tracks
```
Stream #0: 2ch English (128kbps)
Stream #1: 6ch English Surround (448kbps) ← Main audio
Stream #2: 2ch Spanish (128kbps)
Stream #3: 2ch Commentary (64kbps)
Input: 1,3
Output: Keep English 5.1 + Commentary
```
### TV Episode with Multiple Languages
```
Stream #0: 6ch English (384kbps)
Stream #1: 6ch Spanish (384kbps)
Stream #2: 2ch Commentary (64kbps)
Input: 0,1,2
Output: Keep all (English, Spanish, Commentary)
```
### File with Only One Audio Track
```
Stream #0: 6ch English (448kbps)
Input: (blank or 0)
Output: Keep the only track
```
## FAQ
**Q: What if I provide an invalid stream number?**
A: The tool keeps all streams and logs a warning.
**Q: Can I specify stream ranges like "0-2"?**
A: No, use comma-separated individual numbers: "0,1,2"
**Q: Do I have to answer the prompt for every file?**
A: Yes, this allows different selections per file. Use automatic --filter-audio mode if you want consistent filtering across all files.
**Q: What happens with invalid input like "abc" or "1.5"?**
A: The tool keeps all streams and logs the invalid input. Then continues to the next file.
**Q: Does --interactive work alone?**
A: Yes! If you use --interactive without --filter-audio, filtering is automatically enabled with interactive mode.
**Q: Can I combine this with --language tagging?**
A: Yes! Use: `--filter-audio --interactive --language eng`
This lets you select streams AND tag them with language metadata.
## Integration Points
### When Called
- After audio stream detection in `run_ffmpeg()`
- Before codec selection and FFmpeg command building
- Only if `audio_filter_config.enabled = True` AND `audio_filter_config.interactive = True`
### Stream Information Provided
- **Index**: Stream number in FFmpeg (0-based)
- **Channels**: 2ch, 6ch, etc.
- **Language**: eng, spa, und (undefined), etc.
- **Bitrate**: Detected bitrate in kbps
### What Gets Removed
- All streams NOT selected by user
- Metadata and descriptors for removed streams
- No re-encoding of audio (codec decisions apply per stream)
## Tips & Tricks
### Keeping Only Surround Audio
Most videos have stereo + surround. To keep only 5.1/6ch:
```
Input: 1 (if Stream #1 is 6ch)
```
### Keeping All Commentary
Commentary tracks are usually indexed separately:
```
Input: 0,2,3 (Stream #0 main + #2 and #3 commentary)
```
### English Only
If you have multiple languages:
```
Input: 0,1 (Stream #0 and #1 English only)
```
## Log Output Examples
**Successful Selection**
```
User selected 2 audio stream(s): [1, 3]
Removed 1 audio stream(s): [0, 2]
```
**Invalid Input**
```
User provided invalid audio selection input
Keeping all audio streams
```
**No Selection**
```
Keeping all audio streams
```
## Troubleshooting
**Issue**: Prompt doesn't appear
- **Solution**: Make sure both --filter-audio AND --interactive are specified
**Issue**: Selection is ignored
- **Solution**: Check log file for errors. Verify stream indices exist.
**Issue**: Want automatic mode back
- **Solution**: Use --filter-audio alone (without --interactive)

167
README.md Normal file
View File

@ -0,0 +1,167 @@
# AV1 Batch Video Transcoder
A high-performance batch video transcoding tool using NVIDIA's **AV1 NVENC** codec with intelligent audio/subtitle handling and automatic quality optimization.
## ✨ Key Features
- **8-bit AV1 Encoding** - NVIDIA GPU acceleration (yuv420p, preset p7)
- **Smart Audio Processing** - Auto-detects bitrate, AAC for stereo, EAC3 for 5.1, downmixes, re-encodes only when needed
- **Audio Filtering** - Keep only best English audio + Commentary tracks (remove other languages)
- **Subtitle Embedding** - Auto-detects and embeds subtitles (.vtt, .srt, .ass, .ssa, .sub)
- **Smart Resolution** - Scales 4K→1080p, preserves lower resolutions
- **Two-Phase Encoding** - CQ mode first, automatic Bitrate fallback if size threshold exceeded
- **Automatic Cleanup** - Deletes originals + subtitles after successful encoding
- **Test Mode** - Encode one file, check compression ratio before batch processing
- **Optional Language Tagging** - Tag audio streams with language codes
- **CSV Tracking** - Detailed conversion logs with compression ratios
## 🚀 Quick Start
### Requirements
- **Python 3.8+**
- **FFmpeg** with libfdk-aac support
- **NVIDIA GPU** (GeForce RTX 2060+, Quadro, or newer)
- **NVIDIA CUDA Toolkit** (for av1_nvenc support)
### Installation
```bash
# Clone repository
git clone https://github.com/yourusername/conversion_project.git
cd conversion_project
# Install Python dependencies (if any needed in future)
# pip install -r requirements.txt
```
### Basic Usage
```bash
# Encode a TV folder (smart mode)
python main.py "P:\tv\Show Name"
# Test single file before batch processing
python main.py "P:\tv\Show Name" --test
# Force specific quality (CQ 30)
python main.py "P:\movies\Movie" --cq 30
# Force bitrate mode
python main.py "P:\tv\Show" --m bitrate
# Specific resolution
python main.py "P:\movies" --r 720
# Tag audio with language
python main.py "P:\tv\Show" --language eng
```
## 📖 Documentation
- **[Full Usage Guide](README_RESTRUCTURE.md)** - Detailed commands, features, troubleshooting
- **[Technical Architecture](PROJECT_STRUCTURE.md)** - Module breakdown, workflow, config reference
## ⚙️ Configuration
Edit `config.xml` to customize:
```xml
<!-- CQ quality per content type -->
<cq>
<tv_1080>28</tv_1080>
<tv_720>32</tv_720>
<movie_1080>32</movie_1080>
<movie_720>34</movie_720>
</cq>
<!-- Audio bitrate buckets -->
<audio>
<stereo>
<high>192000</high>
<medium>160000</medium>
</stereo>
<multi_channel>
<medium>448000</medium>
<low>384000</low>
</multi_channel>
</audio>
<!-- Subtitle auto-detection -->
<subtitles>
<enabled>true</enabled>
<extensions>.vtt,.srt,.ass,.ssa,.sub</extensions>
</subtitles>
```
## 📊 Example Output
**Input:**
```
Show.S01E01.mkv (1.5GB)
Show.S01E01.en.vtt (subtitle)
```
**Output:**
```
Show.S01E01 - [EHX].mkv (450MB, subtitle embedded, audio tagged)
```
**Compression:** 1.5GB → 450MB (30% ratio, 70% reduction)
## 🔧 Encoding Specs
| Setting | Value |
|---------|-------|
| Video Codec | AV1 (av1_nvenc) |
| Bit Depth | 8-bit (yuv420p) |
| GPU Preset | p1 (high quality) |
| Audio Codec | AAC |
| Audio Mode | Smart (copy or re-encode) |
| Container | MKV |
| Subtitles | Embedded SRT |
## 🎯 Workflow
1. **Scan** folder for video files
2. **Detect** subtitles, audio streams, resolution
3. **Encode** with AV1 codec (Phase 1: CQ)
4. **Check** size threshold (default 75%)
5. **Retry** with Bitrate mode if needed (Phase 2)
6. **Move** encoded file to original location
7. **Cleanup** original + subtitles + temp files
8. **Log** results to CSV tracker
## 📋 Requirements
- Windows 10/11 or Linux
- NVIDIA GPU with NVENC support
- NVIDIA CUDA Toolkit 11.0+
- FFmpeg compiled with av1_nvenc support
- Python 3.8+
## 🛠️ Troubleshooting
**Files not moving?**
- Check `reduction_ratio_threshold` in config.xml (default 0.75)
- Run with `--test` to see compression ratio
**Subtitles not embedding?**
- Verify filename: `video.en.vtt` or `video.vtt`
- Check config.xml `<subtitles><enabled>true</enabled>`
**Wrong audio quality?**
- Adjust CQ values in config.xml per content type
- Use `--cq` override: `python main.py folder --cq 30`
See [Full Guide](README_RESTRUCTURE.md) for more help.
## 📄 License
MIT
## 📞 Support
For detailed usage, see [README_RESTRUCTURE.md](README_RESTRUCTURE.md)
For technical architecture, see [PROJECT_STRUCTURE.md](PROJECT_STRUCTURE.md)

View File

@ -56,7 +56,7 @@ python main.py "P:\tv\Show" --language eng
## Features ## Features
- **Hardware Encoding**: NVIDIA av1_nvenc (10-bit p010le, preset p1) - **Hardware Encoding**: NVIDIA av1_nvenc (8-bit yuv420p, preset p7)
- **Smart Audio**: Analyzes streams, re-encodes excessive bitrate, preserves good quality - **Smart Audio**: Analyzes streams, re-encodes excessive bitrate, preserves good quality
- **Smart Video**: Detects source resolution, scales 4K→1080p, preserves lower resolutions - **Smart Video**: Detects source resolution, scales 4K→1080p, preserves lower resolutions
- **Subtitle Detection**: Auto-finds and embeds subtitles (vtt, srt, ass, ssa, sub) - **Subtitle Detection**: Auto-finds and embeds subtitles (vtt, srt, ass, ssa, sub)
@ -83,7 +83,7 @@ Edit `config.xml` to customize:
1. **Detect subtitles**: Looks for matching `.en.vtt`, `.srt`, etc. 1. **Detect subtitles**: Looks for matching `.en.vtt`, `.srt`, etc.
2. **Analyze source**: Resolution, audio streams, bitrates 2. **Analyze source**: Resolution, audio streams, bitrates
3. **FFmpeg encode**: 3. **FFmpeg encode**:
- Video: AV1 NVENC (10-bit p010le) - Video: AV1 NVENC (8-bit yuv420p)
- Audio: Per-stream decisions (copy or re-encode) - Audio: Per-stream decisions (copy or re-encode)
- Subtitles: Embedded as SRT (if found) - Subtitles: Embedded as SRT (if found)
4. **Size check**: Compare output vs original (default 75% threshold) 4. **Size check**: Compare output vs original (default 75% threshold)

View File

@ -15,10 +15,10 @@
<extensions>.mkv,.mp4</extensions> <extensions>.mkv,.mp4</extensions>
<!-- File name tags to skip/ignore --> <!-- File name tags to skip/ignore -->
<ignore_tags>ehx</ignore_tags> <!-- ,megusta --> <ignore_tags>ehx,._</ignore_tags> <!-- ehx = encoded tag, ._ = macOS metadata files -->
<!-- Reduction ratio threshold: output must be <= this % of original or encoding fails --> <!-- Reduction ratio threshold: output must be <= this % of original or encoding fails -->
<reduction_ratio_threshold>0.75</reduction_ratio_threshold> <reduction_ratio_threshold>0.85</reduction_ratio_threshold>
<!-- Subtitle settings --> <!-- Subtitle settings -->
<subtitles> <subtitles>
@ -27,6 +27,13 @@
<codec>srt</codec> <codec>srt</codec>
</subtitles> </subtitles>
<!-- Audio track filtering: keep only best English audio + Commentary -->
<audio_filter>
<enabled>false</enabled>
<!-- When true: keeps primary English audio (most channels/bitrate) + any Commentary tracks -->
<!-- When false: keeps all audio tracks -->
</audio_filter>
<!-- Audio language tag --> <!-- Audio language tag -->
<audio_language>eng</audio_language> <audio_language>eng</audio_language>
</general> </general>
@ -44,12 +51,24 @@
ENCODE SETTINGS ENCODE SETTINGS
============================= --> ============================= -->
<encode> <encode>
<!-- CQ defaults (per resolution / content type) --> <!-- CQ defaults (per resolution / content type / encoder) -->
<cq> <cq>
<tv_1080>30</tv_1080> <av1>
<tv_720>34</tv_720> <tv_1080>32</tv_1080>
<movie_1080>32</movie_1080> <tv_720>30</tv_720>
<movie_720>34</movie_720> <anime_1080>32</anime_1080>
<anime_720>30</anime_720>
<movie_1080>32</movie_1080>
<movie_720>30</movie_720>
</av1>
<hevc>
<tv_1080>28</tv_1080>
<tv_720>26</tv_720>
<anime_1080>28</anime_1080>
<anime_720>26</anime_720>
<movie_1080>28</movie_1080>
<movie_720>26</movie_720>
</hevc>
</cq> </cq>
<!-- Fallback bitrate-based mode --> <!-- Fallback bitrate-based mode -->

View File

@ -447,3 +447,204 @@ tv,Supernatural,Supernatural - S06E21 - Let It Bleed x265 AC3 Bluray-1080p HiQVE
tv,Supernatural,Supernatural - S06E22 - The Man Who Knew Too Much x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1257.75,561.37,44.6,1920x1080,1920x1080,1,34,CQ tv,Supernatural,Supernatural - S06E22 - The Man Who Knew Too Much x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1257.75,561.37,44.6,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S05E01 - Sympathy for the Devil x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1286.7,512.54,39.8,1920x1080,1920x1080,1,34,CQ tv,Supernatural,Supernatural - S05E01 - Sympathy for the Devil x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1286.7,512.54,39.8,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,"Supernatural - S05E02 - Good God, Y'All! x265 AC3 Bluray-1080p HiQVE - [EHX].mkv",1290.8,640.05,49.6,1920x1080,1920x1080,1,34,CQ tv,Supernatural,"Supernatural - S05E02 - Good God, Y'All! x265 AC3 Bluray-1080p HiQVE - [EHX].mkv",1290.8,640.05,49.6,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S05E05 - Fallen Idols x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1224.68,489.8,40.0,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S05E06 - I Believe the Children Are Our Future x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1147.5,417.19,36.4,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S05E07 - The Curious Case of Dean Winchester x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1092.35,397.79,36.4,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S05E08 - Changing Channels x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1220.88,621.4,50.9,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S05E09 - The Real Ghostbusters x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1172.84,520.0,44.3,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S05E10 - Abandon All Hope x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1093.89,444.87,40.7,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,"Supernatural - S05E11 - Sam, Interrupted x265 AC3 Bluray-1080p HiQVE - [EHX].mkv",1155.62,467.1,40.4,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S05E12 - Swap Meat x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1222.52,506.77,41.5,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S05E13 - The Song Remains the Same x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1116.16,417.32,37.4,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S05E14 - My Bloody Valentine x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1209.17,474.82,39.3,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S05E15 - Dead Men Don't Wear Plaid x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1170.22,485.67,41.5,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S05E16 - Dark Side of the Moon x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1148.56,450.47,39.2,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S05E17 - 99 Problems x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1147.16,458.51,40.0,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S05E18 - Point of No Return x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1138.18,450.57,39.6,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S05E19 - Hammer of the Gods x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1126.81,451.45,40.1,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S05E20 - The Devil You Know x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1100.01,387.27,35.2,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S05E21 - Two Minutes To Midnight x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1059.37,405.11,38.2,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S05E22 - Swan Song x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1164.41,506.82,43.5,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S08E01 - We Need To Talk About Kevin x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1216.44,508.67,41.8,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,"Supernatural - S08E02 - What's Up, Tiger Mommy x265 AC3 Bluray-1080p HiQVE - [EHX].mkv",1163.27,516.16,44.4,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S08E03 - Heartache x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1156.34,439.41,38.0,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S08E04 - Bitten x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1272.57,691.04,54.3,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S08E05 - Blood Brother x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1110.07,476.2,42.9,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S08E06 - Southern Comfort x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1232.93,544.38,44.2,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S08E07 - A Little Slice of Kevin x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1142.88,529.87,46.4,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S08E08 - Hunteri Heroici x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1245.13,559.72,45.0,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S08E09 - Citizen Fang x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1160.86,453.76,39.1,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S08E10 - Torn and Frayed x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1192.44,458.52,38.5,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S08E11 - LARP and the Real Girl x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1193.99,551.28,46.2,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S08E12 - As Time Goes By x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1201.86,495.68,41.2,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S08E13 - Everybody Hates Hitler x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1180.93,466.07,39.5,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S08E14 - Trial and Error x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1199.3,474.89,39.6,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S08E15 - Man's Best Friend with Benefits x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1168.65,440.69,37.7,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S08E16 - Remember the Titans x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1068.49,409.04,38.3,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,"Supernatural - S08E17 - Goodbye, Stranger x265 AC3 Bluray-1080p HiQVE - [EHX].mkv",1068.26,423.48,39.6,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S08E18 - Freaks and Geeks x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1083.2,456.58,42.2,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S08E19 - Taxi Driver x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1119.6,522.02,46.6,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S08E20 - Pac-Man Fever x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1150.82,446.7,38.8,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S08E21 - The Great Escapist x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1182.49,470.16,39.8,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S08E22 - Clip Show x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1128.71,529.95,47.0,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S08E23 - Sacrifice x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1123.91,486.99,43.3,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S14E01 - Stranger in a Strange Land x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1077.42,392.43,36.4,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S14E02 - Gods and Monsters x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1056.56,340.4,32.2,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S14E03 - The Scar x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1139.18,418.79,36.8,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S14E04 - Mint Condition x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1237.48,519.9,42.0,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S14E05 - Nightmare Logic x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1186.46,443.25,37.4,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S14E06 - Optimism x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1161.41,436.32,37.6,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S14E07 - Unhuman Nature x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1144.54,432.86,37.8,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S14E08 - Byzantium x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1201.5,399.35,33.2,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S14E09 - The Spear x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1114.74,405.12,36.3,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S14E10 - Nihilism x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1096.07,372.62,34.0,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S14E11 - Damaged Goods x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1144.87,422.42,36.9,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S14E12 - Prophet and Loss x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,998.45,330.98,33.1,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S14E13 - Lebanon x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1169.02,408.11,34.9,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S14E14 - Ouroboros x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1085.86,376.39,34.7,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S14E15 - Peace of Mind x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1209.11,476.01,39.4,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S14E16 - Don't Go in the Woods x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,998.67,353.21,35.4,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S14E17 - Game Night x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1171.18,478.27,40.8,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S14E18 - Absence x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1149.74,496.79,43.2,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S14E19 - Jack in the Box x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1119.57,345.82,30.9,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S14E20 - Moriah x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1194.42,467.3,39.1,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,"Supernatural - S11E01 - Out of the Darkness, Into the Fire x265 AC3 Bluray-1080p HiQVE - [EHX].mkv",1081.05,491.08,45.4,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S11E02 - Form and Void x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1150.4,441.72,38.4,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S11E03 - The Bad Seed x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1000.66,354.67,35.4,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S11E04 - Baby x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1221.59,650.84,53.3,1920x1080,1920x1080,2,34,CQ
tv,Supernatural,Supernatural - S11E05 - Thin Lizzie x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1111.38,412.77,37.1,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S11E06 - Our Little World x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1121.15,399.25,35.6,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S11E07 - Plush x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1115.48,444.02,39.8,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S11E08 - Just My Imagination x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1003.32,400.98,40.0,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S11E09 - O Brother Where Art Thou x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1056.77,442.89,41.9,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S11E10 - The Devil in the Details x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1057.23,456.3,43.2,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S11E11 - Into the Mystic x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1115.26,457.89,41.1,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S11E12 - Dont You Forget about Me x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1054.6,449.94,42.7,1920x1080,1920x1080,1,34,CQ
tv,Supernatural,Supernatural - S11E13 - Love Hurts x265 AC3 Bluray-1080p HiQVE - [EHX].mkv,1017.88,371.56,36.5,1920x1080,1920x1080,1,34,CQ
tv,Extrapolations,Extrapolations.S01E08.2070.Ecocide.1080p.ATVP.WEB-DL.DDP5.1.H.264-EniaHD - [EHX].mkv,4485.35,821.95,18.3,1920x872,1920x872,2,30,CQ
tv,Extrapolations,Extrapolations.S01E07.2068.The.Going-Away.Party.1080p.ATVP.WEB-DL.DDP5.1.H.264-EniaHD - [EHX].mkv,3977.53,517.86,13.0,1920x872,1920x872,2,30,CQ
tv,Extrapolations,Extrapolations.S01E04.2059.Face.of.God.1080p.ATVP.WEB-DL.DDP5.1.H.264-EniaHD - [EHX].mkv,4348.62,655.87,15.1,1920x872,1920x872,2,30,CQ
tv,Extrapolations,Extrapolations.S01E05.2059.Part.II.Nightbirds.1080p.ATVP.WEB-DL.DDP5.1.H.264-EniaHD - [EHX].mkv,4358.04,875.13,20.1,1920x872,1920x872,2,30,CQ
tv,Extrapolations,Extrapolations.S01E02.2046.Whale.Fall.1080p.ATVP.WEB-DL.DDP5.1.H.264-EniaHD - [EHX].mkv,4506.01,919.87,20.4,1920x872,1920x872,2,30,CQ
tv,Extrapolations,Extrapolations.S01E06.2066.Lola.1080p.ATVP.WEB-DL.DDP5.1.H.264-EniaHD - [EHX].mkv,5080.34,886.64,17.5,1920x872,1920x872,2,30,CQ
tv,Extrapolations,Extrapolations.S01E03.2047.The.Fifth.Question.1080p.ATVP.WEB-DL.DDP5.1.H.264-EniaHD - [EHX].mkv,4775.68,964.11,20.2,1920x872,1920x872,2,30,CQ
tv,Extrapolations,Extrapolations.S01E01.2037.A.Raven.Story.1080p.ATVP.WEB-DL.DDP5.1.H.264-EniaHD - [EHX].mkv,4308.18,1049.28,24.4,1920x872,1920x872,2,30,CQ
movie,N/A,Superman (2025) x265 EAC3 7.1 Bluray-1080p Ghost - [EHX].mkv,8364.57,4374.49,52.3,1920x1080,1920x1080,4,32,CQ
anime,The Case Study of Vanitas (2021),[sam] Vanitas no Carte - 02 [BD 1080p FLAC] [8822B4BC] - [EHX].mkv,1662.26,248.98,15.0,1920x1080,1920x1080,2,32,CQ
anime,The Case Study of Vanitas (2021),[sam] Vanitas no Carte - 03 [BD 1080p FLAC] [BDE63D2B] - [EHX].mkv,1540.47,251.65,16.3,1920x1080,1920x1080,2,32,CQ
anime,The Case Study of Vanitas (2021),[sam] Vanitas no Carte - 04 [BD 1080p FLAC] [4B388837] - [EHX].mkv,1841.37,303.34,16.5,1920x1080,1920x1080,2,32,CQ
anime,The Case Study of Vanitas (2021),[sam] Vanitas no Carte - 05 [BD 1080p FLAC] [03D15E74] - [EHX].mkv,1533.1,279.44,18.2,1920x1080,1920x1080,2,32,CQ
anime,The Case Study of Vanitas (2021),[sam] Vanitas no Carte - 06 [BD 1080p FLAC] [8498E1EE] - [EHX].mkv,1851.33,343.69,18.6,1920x1080,1920x1080,2,32,CQ
movie,N/A,xXx - Return of Xander Cage (2017) x264 TrueHD Atmos 7.1 Bluray-1080p DDR - [EHX].mkv,14066.19,3230.54,23.0,1920x800,1920x800,3,32,CQ
anime,The Case Study of Vanitas (2021),[sam] Vanitas no Carte - 07 [BD 1080p FLAC] [B24C2A72] - [EHX].mkv,1252.42,256.39,20.5,1920x1080,1920x1080,2,32,CQ
anime,The Case Study of Vanitas (2021),[sam] Vanitas no Carte - 08 [BD 1080p FLAC] [133E6216] - [EHX].mkv,1340.99,214.87,16.0,1920x1080,1920x1080,2,32,CQ
anime,The Case Study of Vanitas (2021),[sam] Vanitas no Carte - 09 [BD 1080p FLAC] [90B63B29] - [EHX].mkv,1431.18,246.63,17.2,1920x1080,1920x1080,2,32,CQ
anime,The Case Study of Vanitas (2021),[sam] Vanitas no Carte - 10 [BD 1080p FLAC] [9EB21FD3] - [EHX].mkv,1478.88,280.75,19.0,1920x1080,1920x1080,2,32,CQ
anime,The Case Study of Vanitas (2021),[sam] Vanitas no Carte - 11 [BD 1080p FLAC] [39EC1E6A] - [EHX].mkv,1271.25,245.56,19.3,1920x1080,1920x1080,2,32,CQ
anime,The Case Study of Vanitas (2021),[sam] Vanitas no Carte - 12 [BD 1080p FLAC] [41A14681] - [EHX].mkv,1557.74,243.59,15.6,1920x1080,1920x1080,2,32,CQ
anime,The Case Study of Vanitas (2021),The Case Study of Vanitas - S01E01 - Mémoire 1 - Vanitas ―In the Event of Rusty Hopes― x265 FLAC Bluray-1080p sam - [EHX].mkv,2254.26,369.91,16.4,1920x1080,1920x1080,2,32,CQ
anime,The Case Study of Vanitas (2021),The Case Study of Vanitas - S01E13 - Mémoire 13 - Forêt d'argent ―A Chance Encounter― x265 FLAC Bluray-1080p sam - [EHX].mkv,1769.7,384.47,21.7,1920x1080,1920x1080,2,32,CQ
anime,The Case Study of Vanitas (2021),The Case Study of Vanitas - S01E14 - Mémoire 14 - Château de sorciére ―The Witch and the Young Man― x265 FLAC Bluray-1080p sam - [EHX].mkv,1526.89,251.6,16.5,1920x1080,1920x1080,2,32,CQ
anime,The Case Study of Vanitas (2021),The Case Study of Vanitas - S01E15 - Mémoire 15 - Oiseau et ciel ―The d'Apchiers' Vampire― x265 FLAC Bluray-1080p sam - [EHX].mkv,1659.94,288.39,17.4,1920x1080,1920x1080,2,32,CQ
anime,The Case Study of Vanitas (2021),The Case Study of Vanitas - S01E16 - Mémoire 16 - Chasse aux vampires ―The Beast― x265 FLAC Bluray-1080p sam - [EHX].mkv,1893.39,312.18,16.5,1920x1080,1920x1080,2,32,CQ
anime,The Case Study of Vanitas (2021),The Case Study of Vanitas - S01E17 - Mémoire 17 - Vengeance ―Hands Upon a Nightmare― x265 FLAC Bluray-1080p sam - [EHX].mkv,2111.03,365.15,17.3,1920x1080,1920x1080,2,32,CQ
anime,The Case Study of Vanitas (2021),The Case Study of Vanitas - S01E18 - Mémoire 18 - Avec toi ―Just the Two of Us― x265 FLAC Bluray-1080p sam - [EHX].mkv,1620.1,286.11,17.7,1920x1080,1920x1080,2,32,CQ
anime,The Case Study of Vanitas (2021),The Case Study of Vanitas - S01E19 - Mémoire 19 - Canorus ―Snow Flower― x265 FLAC Bluray-1080p sam - [EHX].mkv,1876.92,395.46,21.1,1920x1080,1920x1080,2,32,CQ
anime,The Case Study of Vanitas (2021),The Case Study of Vanitas - S01E20 - Mémoire 20 - Mal d'amour ―The Incurable Disease― x265 FLAC Bluray-1080p sam - [EHX].mkv,1336.24,234.84,17.6,1920x1080,1920x1080,2,32,CQ
anime,The Case Study of Vanitas (2021),The Case Study of Vanitas - S01E21 - Mémoire 21 - Un autre ―Scar― x265 FLAC Bluray-1080p sam - [EHX].mkv,1359.08,229.23,16.9,1920x1080,1920x1080,2,32,CQ
anime,The Case Study of Vanitas (2021),The Case Study of Vanitas - S01E22 - Mémoire 22 - Rencontre ―Blue Night― x265 FLAC Bluray-1080p sam - [EHX].mkv,1448.32,223.05,15.4,1920x1080,1920x1080,2,32,CQ
anime,The Case Study of Vanitas (2021),The Case Study of Vanitas - S01E23 - Mémoire 23 - Pleuvoir ―Tears like Rain― x265 FLAC Bluray-1080p sam - [EHX].mkv,2601.41,396.97,15.3,1920x1080,1920x1080,2,32,CQ
anime,The Case Study of Vanitas (2021),The Case Study of Vanitas - S01E24 - Mémoire 24 - Après la pluie ―His Wish― x265 FLAC Bluray-1080p sam - [EHX].mkv,1991.11,303.87,15.3,1920x1080,1920x1080,2,32,CQ
anime,The Case Study of Vanitas (2021),[sam] Vanitas no Carte - NCED 1 [BD 1080p FLAC] [F919673C] - [EHX].mkv,115.5,10.38,9.0,1920x1080,1920x1080,2,32,CQ
anime,The Case Study of Vanitas (2021),[sam] Vanitas no Carte - NCOP 1 [BD 1080p FLAC] [ACE65BAF] - [EHX].mkv,99.75,21.82,21.9,1920x1080,1920x1080,1,32,CQ
anime,Sword of the Demon Hunter - Kijin Gentosho (2025),Sword of the Demon Hunter - Kijin Gentosho - S01E01 - Demons and Humans x264 AAC WEBDL-1080p VARYG - [EHX].mkv,2230.88,482.25,21.6,1920x1080,1920x1080,2,32,CQ
anime,Sword of the Demon Hunter - Kijin Gentosho (2025),Sword of the Demon Hunter - Kijin Gentosho - S01E02 - The Demon's Daughter x264 AAC WEBDL-1080p VARYG - [EHX].mkv,975.24,165.89,17.0,1920x1080,1920x1080,2,32,CQ
anime,Sword of the Demon Hunter - Kijin Gentosho (2025),Sword of the Demon Hunter - Kijin Gentosho - S01E03 - The Devourer (Part 1) x264 AAC WEBDL-1080p VARYG - [EHX].mkv,992.22,169.73,17.1,1920x1080,1920x1080,2,32,CQ
anime,Sword of the Demon Hunter - Kijin Gentosho (2025),Sword of the Demon Hunter - Kijin Gentosho - S01E04 - The Devourer (Part 2) x264 AAC WEBDL-1080p VARYG - [EHX].mkv,991.38,174.69,17.6,1920x1080,1920x1080,2,32,CQ
anime,Sword of the Demon Hunter - Kijin Gentosho (2025),Sword of the Demon Hunter - Kijin Gentosho - S01E05 - The Garden of Happiness (Part 1) x264 AAC WEBDL-1080p VARYG - [EHX].mkv,990.18,199.98,20.2,1920x1080,1920x1080,2,32,CQ
anime,Sword of the Demon Hunter - Kijin Gentosho (2025),Sword of the Demon Hunter - Kijin Gentosho - S01E06 - The Garden of Happiness (Part 2) x264 AAC WEBDL-1080p VARYG - [EHX].mkv,988.98,203.36,20.6,1920x1080,1920x1080,2,32,CQ
anime,Sword of the Demon Hunter - Kijin Gentosho (2025),Sword of the Demon Hunter - Kijin Gentosho - S01E07 - The Haunting of Kudanzaka x264 AAC WEBDL-1080p VARYG - [EHX].mkv,989.27,168.54,17.0,1920x1080,1920x1080,2,32,CQ
anime,Sword of the Demon Hunter - Kijin Gentosho (2025),Sword of the Demon Hunter - Kijin Gentosho - S01E08 - Blossoming Dreams of the Kanzashi (Part 1) x264 AAC WEBDL-1080p VARYG - [EHX].mkv,989.56,208.83,21.1,1920x1080,1920x1080,2,32,CQ
anime,Sword of the Demon Hunter - Kijin Gentosho (2025),Sword of the Demon Hunter - Kijin Gentosho - S01E09 - Blossoming Dreams of the Kanzashi (Part 2) x264 AAC WEBDL-1080p VARYG - [EHX].mkv,988.53,204.37,20.7,1920x1080,1920x1080,2,32,CQ
anime,Sword of the Demon Hunter - Kijin Gentosho (2025),Sword of the Demon Hunter - Kijin Gentosho - S01E10 - Harlot in the Rain x264 AAC WEBDL-1080p VARYG - [EHX].mkv,990.33,202.56,20.5,1920x1080,1920x1080,2,32,CQ
anime,Sword of the Demon Hunter - Kijin Gentosho (2025),Sword of the Demon Hunter - Kijin Gentosho - S01E11 - Drunken Dreams of Lingering Snow (Part 1) x264 AAC WEBDL-1080p VARYG - [EHX].mkv,992.92,172.67,17.4,1920x1080,1920x1080,2,32,CQ
anime,Sword of the Demon Hunter - Kijin Gentosho (2025),Sword of the Demon Hunter - Kijin Gentosho - S01E12 - Drunken Dreams of Lingering Snow (Part 2) x264 AAC WEBDL-1080p VARYG - [EHX].mkv,989.34,199.49,20.2,1920x1080,1920x1080,2,32,CQ
movie,N/A,A New Era DC Takes Off.mkv,151.36,57.92,38.3,1920x1080,1280x720,1,34,CQ
movie,N/A,Adventures in the Making of “Superman”.mkv,1885.82,608.37,32.3,1920x1080,1280x720,1,34,CQ
movie,N/A,Breaking News The Daily Planet Returns.mkv,174.45,70.86,40.6,1920x1080,1280x720,1,34,CQ
movie,N/A,Icons Forever Supermans Enduring Legacy.mkv,196.44,73.29,37.3,1920x1080,1280x720,1,34,CQ
movie,N/A,Krypto Short School Bus Scuffle.mkv,169.9,55.95,32.9,1920x1080,1280x720,1,34,CQ
movie,N/A,Kryptunes The Music of “Superman”.mkv,209.9,75.31,35.9,1920x1080,1280x720,1,34,CQ
movie,N/A,Lex Luthor The Mind of a Master Villain.mkv,172.32,62.11,36.0,1920x1080,1280x720,1,34,CQ
movie,N/A,Pawns to Pixels Krypto Is Born.mkv,185.04,69.84,37.7,1920x1080,1280x720,1,34,CQ
movie,N/A,The Justice Gang.mkv,338.06,114.74,33.9,1920x1080,1280x720,1,34,CQ
movie,N/A,The Ultimate Villain.mkv,164.36,74.57,45.4,1920x1080,1280x720,1,34,CQ
movie,N/A,2026-01-03 09-23-11 - [EHX].mkv,845.34,133.54,15.8,3840x2160,1920x1080,1,32,CQ
movie,N/A,Pirates of the Caribbean - Dead Man's Chest (2006) (1080p BluRay x265 10bit Tigole) - [EHX].mkv,9134.59,4091.91,44.8,1920x806,1920x806,2,27,CQ
movie,N/A,Pirates of the Caribbean - Dead Man's Chest (2006) (1080p BluRay x265 10bit Tigole) - Copy - [EHX].mkv,9134.59,3632.85,39.8,1920x806,1920x806,0,28,CQ
movie,N/A,Pirates of the Caribbean - At World's End (2007) (1080p BluRay x265 10bit Tigole) - [EHX].mkv,9795.92,3764.59,38.4,1920x800,1920x800,1,28,CQ
movie,N/A,Pirates of the Caribbean - The Curse of the Black Pearl (2003) (1080p BluRay x265 10bit Tigole) - [EHX].mkv,8626.32,3549.92,41.2,1920x800,1920x800,4,28,CQ
movie,N/A,Pirates of the Caribbean - Dead Men Tell No Tales (2017) (1080p BluRay x265 10bit Tigole) - [EHX].mkv,8415.25,2889.53,34.3,1920x800,1920x800,1,28,CQ
movie,N/A,Deleted Scenes.mkv,67.72,51.41,75.9,1920x800,1920x800,1,28,CQ
movie,N/A,Gallery - Jerry Bruckheimer Photo Diary.mkv,33.16,25.72,77.6,1920x1080,1920x1080,1,28,CQ
movie,N/A,Pirates of the Caribbean - On Stranger Tides (2011) (1080p BluRay x265 10bit Tigole) - [EHX].mkv,7070.29,2401.09,34.0,1920x800,1920x800,2,28,CQ
tv,Dimension 20,Dimension 20 - S27E01 - Welcome to the Wastes - [EHX].mkv,3929.25,1665.15,42.4,1920x1080,1920x1080,1,32,CQ
movie,N/A,Superman (2025) x265 EAC3 7.1 Bluray-1080p Ghost - Copy - [EHX].mkv,8364.57,3891.43,46.5,1920x1080,1920x1080,4,28,CQ
movie,N/A,The Roundup (2022) x265 AAC 5.1 Bluray-1080p Tigole - [EHX].mkv,5702.94,2383.35,41.8,1920x804,1920x804,2,28,CQ
movie,N/A,Wolf Children (2012) x264 AC3 5.1 Bluray-1080p RH - [EHX].mkv,4453.91,1929.93,43.3,1920x1080,1920x1080,3,32,CQ
movie,N/A,The Intern (2015) x265 AAC 5.1 Bluray-1080p Tigole - [EHX].mkv,5020.75,2681.95,53.4,1920x1080,1920x1080,1,28,CQ
movie,N/A,The.Suicide.Squad.2021.1080p.HMAX.WEB-DL.DDP5.1.Atmos.X.264-EVO - [EHX].mkv,5220.52,3193.39,61.2,1920x1012,1920x1012,1,32,CQ
movie,N/A,Venom - The Last Dance (2024) x265 EAC3 5.1 Bluray-1080p Radarr - [EHX].mkv,5722.93,1798.15,31.4,1920x804,1920x804,1,28,CQ
movie,N/A,Meet the Fockers (2004) 1080p 10bit Bluray x265 HEVC [Org DD 5.1 Hindi + DD 5.1 English] MSubs ~ TombDoc - [EHX].mkv,4453.37,1639.66,36.8,1920x1080,1280x720,2,30,CQ
movie,N/A,Meet the Parents (2000) 1080p 10bit Bluray x265 HEVC [Org DD 5.1 Hindi + DD 5.1 English] MSubs ~ TombDoc - [EHX].mkv,4190.09,1167.67,27.9,1920x1080,1280x720,2,30,CQ
movie,N/A,Little Fockers (2010) 1080p 10bit Bluray x265 HEVC [Org DD 5.1 Hindi + DD 5.1 English] MSubs ~ TombDoc - [EHX].mkv,3753.92,934.35,24.9,1920x1040,1280x720,2,30,CQ
movie,N/A,Premium Rush (2012) x265 AAC 5.1 Bluray-1080p afm72 - [EHX].mkv,4184.15,2174.93,52.0,1920x800,1920x1080,1,28,CQ
movie,N/A,Captain America - Brave New World (2025) x265 EAC3 7.1 Bluray-1080p Silence - [EHX].mkv,5999.46,2240.25,37.3,1920x800,1920x800,3,28,CQ
movie,N/A,A New Era DC Takes Off.mkv,151.36,112.09,74.1,1920x1080,1920x1080,1,28,CQ
movie,N/A,Adventures in the Making of “Superman”.mkv,1885.82,1191.9,63.2,1920x1080,1920x1080,1,28,CQ
movie,N/A,Lex Luthor The Mind of a Master Villain.mkv,172.32,122.45,71.1,1920x1080,1920x1080,1,28,CQ
movie,N/A,Kryptunes The Music of “Superman”.mkv,209.9,155.56,74.1,1920x1080,1920x1080,1,28,CQ
movie,N/A,Breaking News The Daily Planet Returns.mkv,174.45,139.55,80.0,1920x1080,1920x1080,1,28,CQ
movie,N/A,Icons Forever Supermans Enduring Legacy.mkv,196.44,146.85,74.8,1920x1080,1920x1080,1,28,CQ
movie,N/A,The Justice Gang.mkv,338.06,219.86,65.0,1920x1080,1920x1080,1,28,CQ
movie,N/A,Pawns to Pixels Krypto Is Born.mkv,185.04,137.35,74.2,1920x1080,1920x1080,1,28,CQ
movie,N/A,Krypto Short School Bus Scuffle.mkv,169.9,113.54,66.8,1920x1080,1920x1080,1,28,CQ
movie,N/A,Ponyo (2008) [1080p x265 HEVC 10bit BluRay Dual Audio AAC 5.1] [Prof] - [EHX].mkv,5677.51,2589.26,45.6,1920x1080,1920x1080,2,28,CQ
movie,N/A,Castle in the Sky (1986) x265 AAC 5.1 Bluray-1080p Prof - [EHX].mkv,5698.25,2878.22,50.5,1920x1080,1920x1080,2,28,CQ
anime,2.5 Dimensional Seduction (2024),2.5.Dimensional.Seduction.2024.S01E01.REPACK2.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold - [EHX].mkv,902.7,271.03,30.0,1920x1080,1920x1080,2,28,CQ
anime,2.5 Dimensional Seduction (2024),2.5.Dimensional.Seduction.2024.S01E02.REPACK2.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold - [EHX].mkv,1062.31,225.84,21.3,1920x1080,1920x1080,2,28,CQ
anime,2.5 Dimensional Seduction (2024),2.5.Dimensional.Seduction.2024.S01E03.REPACK2.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold - [EHX].mkv,1071.07,253.31,23.7,1920x1080,1920x1080,2,28,CQ
anime,2.5 Dimensional Seduction (2024),2.5.Dimensional.Seduction.2024.S01E04.REPACK2.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold - [EHX].mkv,916.31,261.55,28.5,1920x1080,1920x1080,2,28,CQ
anime,2.5 Dimensional Seduction (2024),2.5.Dimensional.Seduction.2024.S01E05.REPACK2.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold - [EHX].mkv,1109.18,270.18,24.4,1920x1080,1920x1080,2,28,CQ
anime,2.5 Dimensional Seduction (2024),2.5.Dimensional.Seduction.2024.S01E06.REPACK2.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold - [EHX].mkv,930.07,266.65,28.7,1920x1080,1920x1080,2,28,CQ
anime,2.5 Dimensional Seduction (2024),2.5.Dimensional.Seduction.2024.S01E07.REPACK2.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold - [EHX].mkv,1020.44,245.17,24.0,1920x1080,1920x1080,2,28,CQ
anime,2.5 Dimensional Seduction (2024),2.5.Dimensional.Seduction.2024.S01E08.REPACK2.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold - [EHX].mkv,964.19,241.3,25.0,1920x1080,1920x1080,2,28,CQ
anime,2.5 Dimensional Seduction (2024),2.5.Dimensional.Seduction.2024.S01E09.REPACK2.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold - [EHX].mkv,1370.19,231.42,16.9,1920x1080,1920x1080,2,28,CQ
anime,2.5 Dimensional Seduction (2024),2.5.Dimensional.Seduction.2024.S01E10.REPACK2.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold - [EHX].mkv,1961.91,323.2,16.5,1920x1080,1920x1080,2,28,CQ
anime,2.5 Dimensional Seduction (2024),2.5.Dimensional.Seduction.2024.S01E11.REPACK2.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold - [EHX].mkv,1812.19,282.68,15.6,1920x1080,1920x1080,2,28,CQ
anime,2.5 Dimensional Seduction (2024),2.5.Dimensional.Seduction.2024.S01E12.REPACK2.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold - [EHX].mkv,1750.2,325.31,18.6,1920x1080,1920x1080,2,28,CQ
anime,2.5 Dimensional Seduction (2024),2.5.Dimensional.Seduction.2024.S01E13.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold - [EHX].mkv,1903.86,399.95,21.0,1920x1080,1920x1080,2,28,CQ
anime,2.5 Dimensional Seduction (2024),2.5.Dimensional.Seduction.2024.S01E14.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold - [EHX].mkv,1636.72,332.96,20.3,1920x1080,1920x1080,2,28,CQ
anime,2.5 Dimensional Seduction (2024),2.5.Dimensional.Seduction.2024.S01E15.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold - [EHX].mkv,1374.76,256.48,18.7,1920x1080,1920x1080,2,28,CQ
anime,2.5 Dimensional Seduction (2024),2.5.Dimensional.Seduction.2024.S01E16.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold - [EHX].mkv,1775.36,406.08,22.9,1920x1080,1920x1080,2,28,CQ
anime,2.5 Dimensional Seduction (2024),2.5.Dimensional.Seduction.2024.S01E17.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold - [EHX].mkv,1666.95,419.35,25.2,1920x1080,1920x1080,2,28,CQ
anime,2.5 Dimensional Seduction (2024),2.5.Dimensional.Seduction.2024.S01E18.REPACK.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold - [EHX].mkv,1909.93,304.69,16.0,1920x1080,1920x1080,2,28,CQ
anime,2.5 Dimensional Seduction (2024),2.5.Dimensional.Seduction.2024.S01E19.REPACK.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold - [EHX].mkv,1276.32,406.7,31.9,1920x1080,1920x1080,2,28,CQ
anime,2.5 Dimensional Seduction (2024),2.5.Dimensional.Seduction.2024.S01E20.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold - [EHX].mkv,1241.33,307.68,24.8,1920x1080,1920x1080,2,28,CQ
anime,2.5 Dimensional Seduction (2024),2.5.Dimensional.Seduction.2024.S01E21.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold - [EHX].mkv,1413.57,287.12,20.3,1920x1080,1920x1080,2,28,CQ
anime,2.5 Dimensional Seduction (2024),2.5.Dimensional.Seduction.2024.S01E22.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold - [EHX].mkv,1278.65,358.63,28.0,1920x1080,1920x1080,2,28,CQ
anime,2.5 Dimensional Seduction (2024),2.5.Dimensional.Seduction.2024.S01E23.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold - [EHX].mkv,1112.42,275.71,24.8,1920x1080,1920x1080,2,28,CQ
anime,2.5 Dimensional Seduction (2024),2.5.Dimensional.Seduction.2024.S01E24.REPACK.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold - [EHX].mkv,1138.06,223.54,19.6,1920x1080,1920x1080,2,28,CQ
anime,The Daily Life of a Middle-Aged Online Shopper in Another World (2025),The Daily Life of a Middle-Aged Online Shopper in Another World - S01E01 - An Unfamiliar Forest x264 Opus Bluray-1080p Netaro - [EHX].mkv,1551.71,253.39,16.3,1920x1080,1920x1080,1,32,CQ
anime,The Daily Life of a Middle-Aged Online Shopper in Another World (2025),The Daily Life of a Middle-Aged Online Shopper in Another World - S01E02 - Curry is Justice! x264 Opus Bluray-1080p Netaro - [EHX].mkv,1601.88,256.06,16.0,1920x1080,1920x1080,1,32,CQ
anime,The Daily Life of a Middle-Aged Online Shopper in Another World (2025),The Daily Life of a Middle-Aged Online Shopper in Another World - S01E03 - A Small House in a Big Forest x264 Opus Bluray-1080p Netaro - [EHX].mkv,1564.89,265.71,17.0,1920x1080,1920x1080,1,32,CQ
anime,The Daily Life of a Middle-Aged Online Shopper in Another World (2025),The Daily Life of a Middle-Aged Online Shopper in Another World - S01E04 - Adventurers (Kenichi and His Eight Allies) x264 Opus Bluray-1080p Netaro - [EHX].mkv,1730.43,267.56,15.5,1920x1080,1920x1080,1,32,CQ
anime,The Daily Life of a Middle-Aged Online Shopper in Another World (2025),The Daily Life of a Middle-Aged Online Shopper in Another World - S01E05 - The Moon Over an Old Castle x264 Opus Bluray-1080p Netaro - [EHX].mkv,1593.87,264.18,16.6,1920x1080,1920x1080,1,32,CQ
anime,The Daily Life of a Middle-Aged Online Shopper in Another World (2025),The Daily Life of a Middle-Aged Online Shopper in Another World - S01E06 - The Book Loving x264 Opus Bluray-1080p Netaro - [EHX].mkv,1596.12,297.05,18.6,1920x1080,1920x1080,1,32,CQ
anime,The Daily Life of a Middle-Aged Online Shopper in Another World (2025),The Daily Life of a Middle-Aged Online Shopper in Another World - S01E07 - Creep Forth! x264 Opus Bluray-1080p Netaro - [EHX].mkv,1629.39,261.02,16.0,1920x1080,1920x1080,1,32,CQ
anime,The Daily Life of a Middle-Aged Online Shopper in Another World (2025),The Daily Life of a Middle-Aged Online Shopper in Another World - S01E08 - The Timid Mage x264 Opus Bluray-1080p Netaro - [EHX].mkv,1438.94,242.13,16.8,1920x1080,1920x1080,1,32,CQ
anime,The Daily Life of a Middle-Aged Online Shopper in Another World (2025),"The Daily Life of a Middle-Aged Online Shopper in Another World - S01E09 - So It's a Spider, So What x264 Opus Bluray-1080p Netaro - [EHX].mkv",1557.73,265.76,17.1,1920x1080,1920x1080,1,32,CQ
anime,The Daily Life of a Middle-Aged Online Shopper in Another World (2025),The Daily Life of a Middle-Aged Online Shopper in Another World - S01E10 - The Story of Canals x264 Opus Bluray-1080p Netaro - [EHX].mkv,1562.25,261.33,16.7,1920x1080,1920x1080,1,32,CQ
anime,The Daily Life of a Middle-Aged Online Shopper in Another World (2025),The Daily Life of a Middle-Aged Online Shopper in Another World - S01E11 - Shock! x264 Opus Bluray-1080p Netaro - [EHX].mkv,1624.52,279.0,17.2,1920x1080,1920x1080,1,32,CQ
anime,The Daily Life of a Middle-Aged Online Shopper in Another World (2025),"The Daily Life of a Middle-Aged Online Shopper in Another World - S01E12 - The Unreasonable, Mischievous Princess x264 Opus Bluray-1080p Netaro - [EHX].mkv",1491.54,264.92,17.8,1920x1080,1920x1080,1,32,CQ
anime,The Daily Life of a Middle-Aged Online Shopper in Another World (2025),The Daily Life of a Middle-Aged Online Shopper in Another World - S01E13 - To Sa-Kura x264 Opus Bluray-1080p Netaro - [EHX].mkv,1607.51,269.68,16.8,1920x1080,1920x1080,1,32,CQ

Can't render this file because it has a wrong number of fields in line 14.

View File

@ -42,8 +42,8 @@ def calculate_stream_bitrate(input_file: Path, stream_index: int) -> int:
str(input_file) str(input_file)
] ]
try: try:
probe_result = subprocess.run(probe_cmd, capture_output=True, text=True, check=False) probe_result = subprocess.run(probe_cmd, capture_output=True, text=True, encoding='utf-8', errors='ignore', check=False)
codec_name = probe_result.stdout.strip().lower() if probe_result.returncode == 0 else "aac" codec_name = probe_result.stdout.strip().lower() if probe_result.stdout and probe_result.returncode == 0 else "aac"
except: except:
codec_name = "aac" codec_name = "aac"
@ -64,7 +64,7 @@ def calculate_stream_bitrate(input_file: Path, stream_index: int) -> int:
temp_audio_path temp_audio_path
] ]
logger.debug(f"Extracting audio stream {stream_index} ({codec_name}) to temporary file for bitrate calculation...") logger.debug(f"Extracting audio stream {stream_index} ({codec_name}) to temporary file for bitrate calculation...")
result = subprocess.run(extract_cmd, capture_output=True, text=True, check=False) result = subprocess.run(extract_cmd, capture_output=True, text=True, encoding='utf-8', errors='ignore', check=False)
# Check if extraction succeeded # Check if extraction succeeded
if result.returncode != 0: if result.returncode != 0:
@ -76,7 +76,8 @@ def calculate_stream_bitrate(input_file: Path, stream_index: int) -> int:
# Step 2: Parse bitrate from ffmpeg's output (stderr) # Step 2: Parse bitrate from ffmpeg's output (stderr)
# Look for line like: "bitrate= 457.7kbits/s" # Look for line like: "bitrate= 457.7kbits/s"
bitrate_kbps = 0 bitrate_kbps = 0
for line in result.stderr.split("\n"): stderr_lines = result.stderr if result.stderr else ""
for line in stderr_lines.split("\n"):
if "bitrate=" in line: if "bitrate=" in line:
# Extract bitrate value from line like "size= 352162KiB time=01:45:03.05 bitrate= 457.7kbits/s" # Extract bitrate value from line like "size= 352162KiB time=01:45:03.05 bitrate= 457.7kbits/s"
parts = line.split("bitrate=") parts = line.split("bitrate=")
@ -101,11 +102,14 @@ def calculate_stream_bitrate(input_file: Path, stream_index: int) -> int:
"-of", "default=noprint_wrappers=1:nokey=1:noprint_wrappers=1", "-of", "default=noprint_wrappers=1:nokey=1:noprint_wrappers=1",
temp_audio_path temp_audio_path
] ]
duration_result = subprocess.run(duration_cmd, capture_output=True, text=True, check=True) duration_result = subprocess.run(duration_cmd, capture_output=True, text=True, encoding='utf-8', errors='ignore', check=False)
duration_seconds = float(duration_result.stdout.strip()) try:
duration_seconds = float(duration_result.stdout.strip()) if duration_result.stdout else 1.0
bitrate_kbps = int((file_size_bytes * 8) / duration_seconds / 1000) bitrate_kbps = int((file_size_bytes * 8) / duration_seconds / 1000)
logger.debug(f"Stream {stream_index}: Calculated bitrate from file: {bitrate_kbps} kbps") logger.debug(f"Stream {stream_index}: Calculated bitrate from file: {bitrate_kbps} kbps")
except (ValueError, ZeroDivisionError):
logger.warning(f"Stream {stream_index}: Could not parse duration from ffprobe")
return 0
return bitrate_kbps return bitrate_kbps
@ -126,21 +130,55 @@ def calculate_stream_bitrate(input_file: Path, stream_index: int) -> int:
def get_audio_streams(input_file: Path): def get_audio_streams(input_file: Path):
""" """
Detect audio streams and calculate robust bitrates by extracting each stream. Detect audio streams and calculate robust bitrates by extracting each stream.
Returns list of (index, channels, calculated_bitrate_kbps, language, metadata_bitrate_kbps) Returns list of (index, channels, calculated_bitrate_kbps, language, metadata_bitrate_kbps, title)
""" """
import re
# First, get full ffprobe output to extract language codes and titles
probe_cmd = ["ffprobe", "-v", "info", str(input_file)]
probe_result = subprocess.run(probe_cmd, capture_output=True, text=True, encoding='utf-8', errors='ignore')
# Parse language and title from output
language_map = {}
title_map = {}
stderr_output = probe_result.stderr if probe_result.stderr else ""
for line in stderr_output.split("\n"):
# Match "Stream #0:X(YYY)" where X is stream number, YYY is language
match = re.search(r"Stream #0:(\d+)\((\w{3})\)", line)
if match:
stream_idx = int(match.group(1))
lang_code = match.group(2)
language_map[stream_idx] = lang_code
# Get audio stream details via JSON with tags
cmd = [ cmd = [
"ffprobe","-v","error","-select_streams","a", "ffprobe","-v","error","-select_streams","a",
"-show_entries","stream=index,channels,bit_rate,tags=language", "-show_entries","stream=index,channels,bit_rate,tags",
"-of","json", str(input_file) "-of","json", str(input_file)
] ]
result = subprocess.run(cmd, capture_output=True, text=True) result = subprocess.run(cmd, capture_output=True, text=True, encoding='utf-8', errors='ignore')
data = json.loads(result.stdout) try:
data = json.loads(result.stdout) if result.stdout else {"streams": []}
except (json.JSONDecodeError, TypeError):
data = {"streams": []}
streams = [] streams = []
for stream_num, s in enumerate(data.get("streams", [])): for stream_num, s in enumerate(data.get("streams", [])):
index = s["index"] index = s["index"]
channels = s.get("channels", 2) channels = s.get("channels", 2)
src_lang = s.get("tags", {}).get("language", "und")
# Get language from our parsed map, default to "und"
src_lang = language_map.get(index, "und")
# Get title from tags or from our parsed map
title = ""
if "tags" in s and "title" in s["tags"]:
title = s["tags"]["title"]
elif index in title_map:
title = title_map[index]
bit_rate_meta = int(s.get("bit_rate", 0)) if s.get("bit_rate") else 0 bit_rate_meta = int(s.get("bit_rate", 0)) if s.get("bit_rate") else 0
# Calculate robust bitrate by extracting the audio stream # Calculate robust bitrate by extracting the audio stream
@ -151,7 +189,7 @@ def get_audio_streams(input_file: Path):
calculated_bitrate_kbps = int(bit_rate_meta / 1000) if bit_rate_meta else 160 calculated_bitrate_kbps = int(bit_rate_meta / 1000) if bit_rate_meta else 160
logger.info(f"Stream {index}: Using fallback bitrate {calculated_bitrate_kbps} kbps") logger.info(f"Stream {index}: Using fallback bitrate {calculated_bitrate_kbps} kbps")
streams.append((index, channels, calculated_bitrate_kbps, src_lang, int(bit_rate_meta / 1000) if bit_rate_meta else 0)) streams.append((index, channels, calculated_bitrate_kbps, src_lang, int(bit_rate_meta / 1000) if bit_rate_meta else 0, title))
return streams return streams
@ -161,28 +199,27 @@ def choose_audio_bitrate(channels: int, bitrate_kbps: int, audio_config: dict, i
Choose audio codec and bitrate based on channel count, detected bitrate, and resolution. Choose audio codec and bitrate based on channel count, detected bitrate, and resolution.
Returns tuple: (codec, target_bitrate_bps) Returns tuple: (codec, target_bitrate_bps)
- codec: "aac", "libopus", or "copy" (to preserve original without re-encoding) - codec: "aac" (stereo), "eac3" (5.1), or "copy" (preserve original)
- target_bitrate_bps: target bitrate in bits/sec (0 if using "copy") - target_bitrate_bps: target bitrate in bits/sec (0 if using "copy")
Rules: Rules:
Stereo + 1080p: Stereo + 1080p:
- Above 192k high (192k) with AAC - Above 192k encode to 192k with AAC
- At/below 192k preserve (copy) - At/below 192k preserve (copy)
Stereo + 720p: Stereo + 720p:
- Above 160k medium (160k) with AAC - Above 160k encode to 160k with AAC
- At/below 160k preserve (copy) - At/below 160k preserve (copy)
Multi-channel: Multi-channel (5.1+):
- Below minimum threshold (low setting) preserve original (copy) - Below minimum threshold preserve original (copy)
- Low to medium use low bitrate - Low to medium use EAC3 codec
- Medium and above use medium bitrate
""" """
# Normalize to 2ch or 6ch output # Normalize to 2ch or 6ch output
output_channels = 6 if channels >= 6 else 2 output_channels = 6 if channels >= 6 else 2
if output_channels == 2: if output_channels == 2:
# Stereo logic # Stereo logic - use AAC
if is_1080_class: if is_1080_class:
# 1080p+ stereo # 1080p+ stereo
high_br = audio_config["stereo"]["high"] high_br = audio_config["stereo"]["high"]
@ -203,7 +240,7 @@ def choose_audio_bitrate(channels: int, bitrate_kbps: int, audio_config: dict, i
return ("copy", 0) return ("copy", 0)
else: else:
# Multi-channel (6ch+) logic # Multi-channel (6ch+) logic - use EAC3
low_br = audio_config["multi_channel"]["low"] low_br = audio_config["multi_channel"]["low"]
medium_br = audio_config["multi_channel"]["medium"] medium_br = audio_config["multi_channel"]["medium"]
@ -212,8 +249,193 @@ def choose_audio_bitrate(channels: int, bitrate_kbps: int, audio_config: dict, i
logger.info(f"Multi-channel audio {bitrate_kbps}kbps < {low_br/1000:.0f}k minimum - copying original to avoid artifical inflation") logger.info(f"Multi-channel audio {bitrate_kbps}kbps < {low_br/1000:.0f}k minimum - copying original to avoid artifical inflation")
return ("copy", 0) return ("copy", 0)
elif bitrate_kbps < (medium_br / 1000): elif bitrate_kbps < (medium_br / 1000):
# Below medium, use low # Below medium, use low with EAC3
return ("aac", low_br) return ("eac3", low_br)
else: else:
# Medium and above, use medium # Medium and above, use medium with EAC3
return ("aac", medium_br) return ("eac3", medium_br)
def filter_audio_streams(input_file: Path, streams: list) -> list:
"""
Filter audio streams to keep only best English audio + Commentary tracks.
Args:
input_file: Path to video file
streams: List of (index, channels, bitrate, language, metadata, title) tuples
Returns:
Filtered list of streams (original indices preserved for FFmpeg mapping)
"""
if not streams:
return streams
# Try to get stream metadata (title) to detect commentary
english_tracks = []
commentary_tracks = []
for stream_info in streams:
index, channels, bitrate, language, metadata, title = stream_info
# Check if commentary (in title or metadata)
is_commentary = "comment" in str(title).lower() or "comment" in str(metadata).lower()
# Determine if English (check language field or assume first is English if no language set)
is_english = (language and "eng" in language.lower()) or (not language)
if is_commentary:
commentary_tracks.append((index, channels, bitrate, stream_info))
elif is_english:
english_tracks.append((index, channels, bitrate, stream_info))
# If no English tracks, return original
if not english_tracks:
logger.info("No English audio tracks detected - keeping all audio")
return streams
# Pick best English track (most channels, then highest bitrate)
english_tracks.sort(key=lambda x: (-x[1], -x[2])) # Sort by channels desc, then bitrate desc
best_english = english_tracks[0][3] # Get original stream tuple
logger.info(f"Audio filter: Keeping best English track (index {best_english[0]}: {best_english[1]}ch @ {best_english[2]}kbps)")
# Build result: best English + all commentary
filtered = [best_english] + [ct[3] for ct in commentary_tracks]
if commentary_tracks:
logger.info(f"Audio filter: Also keeping {len(commentary_tracks)} commentary track(s)")
# Log removed tracks
removed_count = len(streams) - len(filtered)
if removed_count > 0:
logger.info(f"Audio filter: Removed {removed_count} non-English audio track(s)")
return filtered
def prompt_user_audio_selection(streams: list) -> list:
"""
Interactively prompt user to select which audio streams to keep.
Args:
streams: List of (index, channels, bitrate, language, metadata, title) tuples
Returns:
Filtered list containing only selected streams
"""
if not streams or len(streams) <= 1:
return streams
print("\n" + "="*80)
print("🎵 AUDIO STREAM SELECTION")
print("="*80)
# Display all streams with details
for index, channels, bitrate, language, metadata, title in streams:
channels_display = f"{channels}ch"
lang_display = language if language != "und" else "undefined"
# Display title if available
if title:
title_display = f" | {title}"
else:
title_display = ""
print(f"\nStream #{index}: {channels_display} | Lang: {lang_display} | Bitrate: {bitrate}kbps{title_display}")
print("\n" + "-"*80)
print("Enter stream numbers to keep (comma-separated, e.g.: 1,2 or just 2)")
print("Leave blank to keep all streams")
print("-"*80)
user_input = input("➜ Keep streams: ").strip()
# If empty, keep all
if not user_input:
print("✅ Keeping all audio streams\n")
return streams
# Parse user input
try:
selected_indices = set()
for part in user_input.split(","):
idx = int(part.strip())
selected_indices.add(idx)
except ValueError:
print("❌ Invalid input. Keeping all streams.")
logger.warning("User provided invalid audio selection input")
return streams
# Filter streams to only selected ones
filtered = [s for s in streams if s[0] in selected_indices]
if not filtered:
print("❌ No valid streams selected. Keeping all streams.")
logger.warning("User selected no valid streams")
return streams
# Log what was selected/removed
removed_count = len(streams) - len(filtered)
print(f"✅ Keeping {len(filtered)} stream(s), removing {removed_count} stream(s)\n")
logger.info(f"User selected {len(filtered)} audio stream(s): {[s[0] for s in filtered]}")
if removed_count > 0:
removed_indices = [s[0] for s in streams if s[0] not in selected_indices]
logger.info(f"Removed {removed_count} audio stream(s): {removed_indices}")
# Return filtered streams without strip_title field - let prompt_for_title_stripping handle that
return filtered
def prompt_for_title_stripping(filtered_streams: list) -> list:
"""
Prompt user to select which streams should have titles stripped.
Args:
filtered_streams: List of (index, channels, bitrate, language, metadata, title, strip_title) tuples
Returns:
Same list with strip_title field updated based on user selection
"""
streams_with_titles = [(s[0], s[5]) for s in filtered_streams if s[5]]
if not streams_with_titles:
return [s + (False,) if len(s) == 6 else s for s in filtered_streams]
print("\n" + "="*80)
print("📝 TITLE METADATA STRIPPING (Optional)")
print("="*80)
print("\nStreams with titles that can be stripped:\n")
for idx, title in streams_with_titles:
print(f" Stream #{idx}: \"{title}\"")
print("\n" + "-"*80)
print("Enter stream numbers to STRIP titles (comma-separated, or leave blank to keep all)")
print("Example: \"1,3\" will strip titles from streams #1 and #3")
print("-"*80)
strip_input = input("➜ Strip titles from: ").strip()
strip_indices = set()
if strip_input:
try:
for part in strip_input.split(","):
idx = int(part.strip())
strip_indices.add(idx)
except ValueError:
print("❌ Invalid input. Keeping all titles.\n")
logger.warning("Invalid title stripping input")
# Add strip_title field to each stream
result = []
for s in filtered_streams:
should_strip = s[0] in strip_indices
result.append(s + (should_strip,))
if strip_indices:
print(f"✅ Will strip titles from stream(s): {sorted(list(strip_indices))}\n")
logger.info(f"User selected to strip titles from streams: {sorted(list(strip_indices))}")
else:
print("✅ Keeping all titles\n")
return result

View File

@ -91,35 +91,47 @@ def load_config_xml(path: Path) -> dict:
if encode_elem is not None: if encode_elem is not None:
cq_elem = encode_elem.find("cq") cq_elem = encode_elem.find("cq")
if cq_elem is not None: if cq_elem is not None:
for child in cq_elem: # Check if CQ has encoder-specific sub-elements (av1, hevc)
if child.text: encoder_elems = list(cq_elem)
cq[child.tag] = int(child.text) if encoder_elems and encoder_elems[0].tag in ["av1", "hevc"]:
# New nested structure with encoder-specific CQ values
for encoder_tag in cq_elem:
if encoder_tag.tag in ["av1", "hevc"]:
cq[encoder_tag.tag] = {}
for child in encoder_tag:
if child.text and child.text.strip():
cq[encoder_tag.tag][child.tag] = int(child.text.strip())
else:
# Old flat structure (backwards compatibility)
for child in cq_elem:
if child.text and child.text.strip():
cq[child.tag] = int(child.text.strip())
fallback_elem = encode_elem.find("fallback") fallback_elem = encode_elem.find("fallback")
if fallback_elem is not None: if fallback_elem is not None:
for child in fallback_elem: for child in fallback_elem:
if child.text: if child.text and child.text.strip():
fallback[child.tag] = child.text fallback[child.tag] = child.text.strip()
filters_elem = encode_elem.find("filters") filters_elem = encode_elem.find("filters")
if filters_elem is not None: if filters_elem is not None:
for child in filters_elem: for child in filters_elem:
if child.text: if child.text and child.text.strip():
filters[child.tag] = child.text filters[child.tag] = child.text.strip()
# --- Audio --- # --- Audio ---
audio = {"stereo": {}, "multi_channel": {}} audio = {"stereo": {}, "multi_channel": {}}
stereo_elem = root.find("audio/stereo") stereo_elem = root.find("audio/stereo")
if stereo_elem is not None: if stereo_elem is not None:
for child in stereo_elem: for child in stereo_elem:
if child.text: if child.text and child.text.strip():
audio["stereo"][child.tag] = int(child.text) audio["stereo"][child.tag] = int(child.text.strip())
multi_elem = root.find("audio/multi_channel") multi_elem = root.find("audio/multi_channel")
if multi_elem is not None: if multi_elem is not None:
for child in multi_elem: for child in multi_elem:
if child.text: if child.text and child.text.strip():
audio["multi_channel"][child.tag] = int(child.text) audio["multi_channel"][child.tag] = int(child.text.strip())
# --- Services (Sonarr/Radarr) --- # --- Services (Sonarr/Radarr) ---
services = {"sonarr": {}, "radarr": {}} services = {"sonarr": {}, "radarr": {}}

View File

@ -4,7 +4,7 @@
import subprocess import subprocess
from pathlib import Path from pathlib import Path
from core.audio_handler import get_audio_streams, choose_audio_bitrate from core.audio_handler import get_audio_streams, choose_audio_bitrate, filter_audio_streams, prompt_user_audio_selection, prompt_for_title_stripping
from core.logger_helper import setup_logger from core.logger_helper import setup_logger
logger = setup_logger(Path(__file__).parent.parent / "logs") logger = setup_logger(Path(__file__).parent.parent / "logs")
@ -12,23 +12,77 @@ logger = setup_logger(Path(__file__).parent.parent / "logs")
def run_ffmpeg(input_file: Path, output_file: Path, cq: int, scale_width: int, scale_height: int, def run_ffmpeg(input_file: Path, output_file: Path, cq: int, scale_width: int, scale_height: int,
src_width: int, src_height: int, filter_flags: str, audio_config: dict, src_width: int, src_height: int, filter_flags: str, audio_config: dict,
method: str, bitrate_config: dict, subtitle_file: Path = None, audio_language: str = None): method: str, bitrate_config: dict, encoder: str = "nvenc", subtitle_files: list = None, audio_language: str = None,
audio_filter_config: dict = None, test_mode: bool = False, strip_all_titles: bool = False):
""" """
Run FFmpeg encode with comprehensive logging. Run FFmpeg encode with comprehensive logging.
Args:
strip_all_titles: If True, strip all title metadata from all audio tracks
Returns tuple: (orig_size, out_size, reduction_ratio) Returns tuple: (orig_size, out_size, reduction_ratio)
""" """
streams = get_audio_streams(input_file) streams = get_audio_streams(input_file)
# Apply audio filter if enabled
if audio_filter_config and audio_filter_config.get("enabled", False):
# Check if pre-selected streams provided
if audio_filter_config.get("preselected"):
# Use pre-selected streams (skip interactive)
preselected_str = audio_filter_config["preselected"]
try:
selected_indices = set()
for part in preselected_str.split(","):
idx = int(part.strip())
selected_indices.add(idx)
# Filter to only selected streams
streams = [s for s in streams if s[0] in selected_indices]
# Add strip_title field (False by default for pre-selected)
streams = [s + (False,) for s in streams]
logger.info(f"Pre-selected audio streams: {[s[0] for s in streams]}")
except ValueError:
logger.warning(f"Invalid audio_select format: {preselected_str}. Using all streams.")
streams = [s + (False,) for s in streams]
else:
# Check if interactive mode requested (via --filter-audio CLI flag)
# If audio_filter_config came from CLI, it has "interactive": True
if "interactive" in audio_filter_config and audio_filter_config.get("interactive", False):
# Interactive audio selection (show prompt to user)
streams = prompt_user_audio_selection(streams)
# Prompt for title stripping after stream selection
streams = prompt_for_title_stripping(streams)
else:
# Automatic filtering from config (keep best English + Commentary)
streams = filter_audio_streams(input_file, streams)
# Add strip_title field (False by default for automatic filtering)
streams = [s + (False,) for s in streams]
else:
# No filtering - add strip_title field as False
streams = [s + (False,) for s in streams]
# Log comprehensive encode settings # Log comprehensive encode settings
header = f"\n🧩 ENCODE SETTINGS" header = f"\n🧩 ENCODE SETTINGS"
logger.info(header) logger.info(header)
print(" ") print(" ")
# Determine encoder display name and settings
if encoder == "av1":
encoder_name = "AV1 NVENC"
encoder_codec = "av1_nvenc"
encoder_preset = "p7"
encoder_pix_fmt = "yuv420p"
encoder_bit_depth = "8-bit"
else: # default hevc = HEVC NVENC
encoder_name = "HEVC NVENC"
encoder_codec = "hevc_nvenc"
encoder_preset = "slow"
encoder_pix_fmt = "p010le"
encoder_bit_depth = "10-bit"
logger.info(f" Video:") logger.info(f" Video:")
logger.info(f" • Source Resolution: {src_width}x{src_height}") logger.info(f" • Source Resolution: {src_width}x{src_height}")
logger.info(f" • Target Resolution: {scale_width}x{scale_height}") logger.info(f" • Target Resolution: {scale_width}x{scale_height}")
logger.info(f" • Encoder: av1_nvenc (preset p1, pix_fmt p010le)") logger.info(f" • Encoder: {encoder_name} (preset {encoder_preset}, {encoder_bit_depth}, pix_fmt {encoder_pix_fmt})")
logger.info(f" • Scale Filter: {filter_flags}") logger.info(f" • Scale Filter: {filter_flags}")
logger.info(f" • Encode Method: {method}") logger.info(f" • Encode Method: {method}")
if method == "CQ": if method == "CQ":
@ -42,7 +96,7 @@ def run_ffmpeg(input_file: Path, output_file: Path, cq: int, scale_width: int, s
logger.info(f" Audio Streams ({len(streams)} detected):") logger.info(f" Audio Streams ({len(streams)} detected):")
print(" ") print(" ")
for (index, channels, avg_bitrate, src_lang, meta_bitrate) in streams: for (index, channels, avg_bitrate, src_lang, meta_bitrate, title, strip_title) in streams:
# Normalize to 2ch or 6ch output # Normalize to 2ch or 6ch output
is_1080_class = scale_height >= 1080 or scale_width >= 1920 is_1080_class = scale_height >= 1080 or scale_width >= 1920
output_channels = 6 if is_1080_class and channels >= 6 else 2 output_channels = 6 if is_1080_class and channels >= 6 else 2
@ -55,28 +109,40 @@ def run_ffmpeg(input_file: Path, output_file: Path, cq: int, scale_width: int, s
action = "ENCODE" action = "ENCODE"
bitrate_display = f"{br/1000:.0f}kbps" bitrate_display = f"{br/1000:.0f}kbps"
line = f" - Stream #{index}: {channels}ch→{output_channels}ch | Lang: {src_lang} | Detected: {avg_bitrate}kbps | Action: {action} | Target: {bitrate_display}" # Include title in display if present
title_info = f" | Title: {title}" if title else ""
line = f" - Stream #{index}: {channels}ch→{output_channels}ch | Lang: {src_lang} | Detected: {avg_bitrate}kbps | Action: {action} | Target: {bitrate_display}{title_info}"
print(line) print(line)
logger.info(line) logger.info(line)
cmd = ["ffmpeg","-y","-i",str(input_file)] cmd = ["ffmpeg","-y","-i",str(input_file)]
# Add subtitle input if present # Add subtitle inputs if present
if subtitle_file: if subtitle_files:
cmd.extend(["-i", str(subtitle_file)]) for sub_file in subtitle_files:
cmd.extend(["-i", str(sub_file)])
# In test mode, only encode first 15 minutes
if test_mode:
cmd.extend(["-t", "900"]) # 900 seconds = 15 minutes
cmd.extend([ cmd.extend([
"-vf",f"scale={scale_width}:{scale_height}:flags={filter_flags}:force_original_aspect_ratio=decrease", "-vf",f"scale={scale_width}:{scale_height}:flags={filter_flags}:force_original_aspect_ratio=decrease",
"-map","0:v","-map","0:a"]) "-map","0:v"])
# Map only selected audio streams
for index, _, _, _, _, _, _ in streams:
cmd.extend(["-map", f"0:{index}"])
# Add subtitle mapping if present # Add subtitle mapping if present
if subtitle_file: if subtitle_files:
cmd.extend(["-map", "1:s"]) for i, _ in enumerate(subtitle_files):
cmd.extend(["-map", f"{i+1}:s"])
else: else:
cmd.extend(["-map", "0:s?"]) cmd.extend(["-map", "0:s?"])
cmd.extend([ cmd.extend([
"-c:v","av1_nvenc","-preset","p1","-pix_fmt","p010le"]) "-c:v", encoder_codec, "-preset", encoder_preset, "-pix_fmt", encoder_pix_fmt])
if method=="CQ": if method=="CQ":
cmd += ["-cq", str(cq)] cmd += ["-cq", str(cq)]
@ -88,7 +154,7 @@ def run_ffmpeg(input_file: Path, output_file: Path, cq: int, scale_width: int, s
bufsize = bitrate_config.get(f"bufsize_{res_key}", "1800k") bufsize = bitrate_config.get(f"bufsize_{res_key}", "1800k")
cmd += ["-b:v", vb, "-maxrate", maxrate, "-bufsize", bufsize] cmd += ["-b:v", vb, "-maxrate", maxrate, "-bufsize", bufsize]
for i, (index, channels, avg_bitrate, src_lang, meta_bitrate) in enumerate(streams): for i, (index, channels, avg_bitrate, src_lang, meta_bitrate, title, strip_title) in enumerate(streams):
# Normalize to 2ch or 6ch output # Normalize to 2ch or 6ch output
is_1080_class = scale_height >= 1080 or scale_width >= 1920 is_1080_class = scale_height >= 1080 or scale_width >= 1920
output_channels = 6 if is_1080_class and channels >= 6 else 2 output_channels = 6 if is_1080_class and channels >= 6 else 2
@ -100,21 +166,41 @@ def run_ffmpeg(input_file: Path, output_file: Path, cq: int, scale_width: int, s
# Only add language metadata if explicitly provided # Only add language metadata if explicitly provided
if audio_language: if audio_language:
cmd += [f"-metadata:s:a:{i}", f"language={audio_language}"] cmd += [f"-metadata:s:a:{i}", f"language={audio_language}"]
# Strip title metadata if requested (but preserve commentary tracks)
should_strip = strip_title or (strip_all_titles and not (title and "commentary" in title.lower()))
if should_strip:
cmd += [f"-metadata:s:a:{i}", "title="]
else: else:
# Re-encode with target bitrate # Re-encode with target bitrate
cmd += [ # EAC3 for multichannel, AAC for stereo
f"-c:a:{i}", codec, if codec == "eac3":
f"-b:a:{i}", str(br), # Enhanced AC-3 (5.1 surround)
f"-ac:{i}", str(output_channels), cmd += [
f"-channel_layout:a:{i}", "5.1" if output_channels == 6 else "stereo" f"-c:a:{i}", "eac3",
] f"-b:a:{i}", str(br),
f"-ac:{i}", str(output_channels),
f"-channel_layout:a:{i}", "5.1"
]
else:
# AAC (stereo)
cmd += [
f"-c:a:{i}", "aac",
f"-b:a:{i}", str(br),
f"-ac:{i}", str(output_channels),
f"-channel_layout:a:{i}", "stereo"
]
# Only add language metadata if explicitly provided # Only add language metadata if explicitly provided
if audio_language: if audio_language:
cmd += [f"-metadata:s:a:{i}", f"language={audio_language}"] cmd += [f"-metadata:s:a:{i}", f"language={audio_language}"]
# Strip title metadata if requested (but preserve commentary tracks)
should_strip = strip_title or (strip_all_titles and not (title and "commentary" in title.lower()))
if should_strip:
cmd += [f"-metadata:s:a:{i}", "title="]
# Add subtitle codec and metadata if subtitles are present # Add subtitle codec and metadata if subtitles are present
if subtitle_file: if subtitle_files:
cmd += ["-c:s", "srt", "-metadata:s:s:0", "language=eng"] cmd += ["-c:s", "srt"]
for i in range(len(subtitle_files)):
cmd += ["-metadata:s:s:" + str(i), "language=eng"]
else: else:
cmd += ["-c:s", "copy"] cmd += ["-c:s", "copy"]

View File

@ -11,7 +11,7 @@ from pathlib import Path
from core.audio_handler import get_audio_streams from core.audio_handler import get_audio_streams
from core.encode_engine import run_ffmpeg from core.encode_engine import run_ffmpeg
from core.logger_helper import setup_logger, setup_failure_logger from core.logger_helper import setup_logger, setup_failure_logger
from core.video_handler import get_source_resolution, determine_target_resolution from core.video_handler import get_source_resolution, get_source_bit_depth, determine_target_resolution
logger = setup_logger(Path(__file__).parent.parent / "logs") logger = setup_logger(Path(__file__).parent.parent / "logs")
failure_logger = setup_failure_logger(Path(__file__).parent.parent / "logs") failure_logger = setup_failure_logger(Path(__file__).parent.parent / "logs")
@ -34,7 +34,7 @@ def _cleanup_temp_files(temp_input: Path, temp_output: Path):
logger.warning(f"Could not delete temp output {temp_output.name}: {e}") logger.warning(f"Could not delete temp output {temp_output.name}: {e}")
def process_folder(folder: Path, cq: int, transcode_mode: str, resolution: str, config: dict, tracker_file: Path, test_mode: bool = False, audio_language: str = None): def process_folder(folder: Path, cq: int, transcode_mode: str, resolution: str, config: dict, tracker_file: Path, test_mode: bool = False, audio_language: str = None, filter_audio: bool = None, audio_select: str = None, encoder: str = "hevc", strip_all_titles: bool = False):
""" """
Process all video files in folder with appropriate encoding settings. Process all video files in folder with appropriate encoding settings.
@ -47,6 +47,10 @@ def process_folder(folder: Path, cq: int, transcode_mode: str, resolution: str,
tracker_file: Path to CSV tracker file tracker_file: Path to CSV tracker file
test_mode: If True, only encode first file and skip final move/cleanup test_mode: If True, only encode first file and skip final move/cleanup
audio_language: Optional language code to tag audio (e.g., 'eng', 'spa'). If None, no tagging applied. audio_language: Optional language code to tag audio (e.g., 'eng', 'spa'). If None, no tagging applied.
filter_audio: If True, show interactive audio selection prompt. If None, use config setting.
audio_select: Pre-selected audio streams (comma-separated, e.g., "1,2"). Skips interactive prompt.
encoder: Video encoder to use - "hevc" for HEVC NVENC 10-bit (default) or "av1" for AV1 NVENC 8-bit.
strip_all_titles: If True, strip all title metadata from all audio tracks.
""" """
if not folder.exists(): if not folder.exists():
print(f"❌ Folder not found: {folder}") print(f"❌ Folder not found: {folder}")
@ -67,30 +71,33 @@ def process_folder(folder: Path, cq: int, transcode_mode: str, resolution: str,
filter_flags = filters_config.get("default","lanczos") filter_flags = filters_config.get("default","lanczos")
folder_lower = str(folder).lower() folder_lower = str(folder).lower()
is_tv = "\\tv\\" in folder_lower or "/tv/" in folder_lower is_tv = "\\tv\\" in folder_lower or "/tv/" in folder_lower
is_anime = "\\anime\\" in folder_lower or "/anime/" in folder_lower
if is_tv: if is_tv:
filter_flags = filters_config.get("tv","bicubic") filter_flags = filters_config.get("tv","bicubic")
elif is_anime:
filter_flags = filters_config.get("anime", filters_config.get("default","lanczos"))
processing_folder = Path(config["processing_folder"]) processing_folder = Path(config["processing_folder"])
processing_folder.mkdir(parents=True, exist_ok=True) processing_folder.mkdir(parents=True, exist_ok=True)
# Determine if we're in smart mode (no explicit mode specified) # Determine encoding mode
is_smart_mode = transcode_mode not in ["cq", "bitrate"] # Default/smart mode is_smart_mode = transcode_mode == "compression" # Try CQ first, then bitrate fallback
is_forced_cq = transcode_mode == "cq" is_forced_cq = transcode_mode == "cq"
is_forced_bitrate = transcode_mode == "bitrate" is_forced_bitrate = transcode_mode == "bitrate"
# Track files for potential retry in smart mode # Track files for potential retry in smart mode
failed_cq_files = [] # List of (file_path, metadata) for CQ failures in smart mode failed_cq_files = [] # List of (file_path, metadata) for CQ failures in compression mode
consecutive_failures = 0 consecutive_failures = 0
max_consecutive = 3 max_consecutive = 3
# Phase 1: Process files with initial mode strategy # Phase 1: Process files with initial mode strategy
print(f"\n{'='*60}") print(f"\n{'='*60}")
if is_smart_mode: if is_smart_mode:
print("📋 MODE: Smart (Try CQ first, retry with Bitrate if needed)") print("📋 MODE: Compression (Try CQ first, retry with Bitrate if needed)")
elif is_forced_cq: elif is_forced_cq:
print("📋 MODE: Forced CQ (skip failures, log them)") print("📋 MODE: CQ (constant quality, skip failures, log them)")
else: else:
print("📋 MODE: Forced Bitrate (skip failures, log them)") print("📋 MODE: Bitrate (bitrate mode only, skip failures, log them)")
print(f"{'='*60}\n") print(f"{'='*60}\n")
skipped_count = 0 skipped_count = 0
@ -111,41 +118,59 @@ def process_folder(folder: Path, cq: int, transcode_mode: str, resolution: str,
print(f"📁 Processing: {file.name}") print(f"📁 Processing: {file.name}")
temp_input = (processing_folder / file.name).resolve() temp_input = (processing_folder / file.name).resolve()
shutil.copy2(file, temp_input)
logger.info(f"Copied {file.name}{temp_input.name}")
# Verify file was copied and is accessible # Check if file already exists in processing folder
if temp_input.exists() and os.access(temp_input, os.R_OK):
source_size = file.stat().st_size
temp_size = temp_input.stat().st_size
# Verify it's complete (same size as source)
if source_size == temp_size:
print(f"✓ Found existing copy in processing folder (verified complete)")
logger.info(f"File already in processing: {file.name} ({temp_size/1e6:.2f} MB verified complete)")
else:
# File exists but incomplete - recopy
print(f"⚠️ Existing copy incomplete ({temp_size/1e6:.2f} MB vs {source_size/1e6:.2f} MB source). Re-copying...")
logger.warning(f"Incomplete copy detected for {file.name}. Re-copying.")
shutil.copy2(file, temp_input)
logger.info(f"Re-copied {file.name}{temp_input.name}")
else:
# File doesn't exist or not accessible - copy it
shutil.copy2(file, temp_input)
logger.info(f"Copied {file.name}{temp_input.name}")
# Verify file is accessible
for attempt in range(3): for attempt in range(3):
if temp_input.exists() and os.access(temp_input, os.R_OK): if temp_input.exists() and os.access(temp_input, os.R_OK):
break break
# Check for matching subtitle file # Check for matching subtitle files (supports multiple)
subtitle_file = None subtitle_files = []
if config.get("general", {}).get("subtitles", {}).get("enabled", True): if config.get("general", {}).get("subtitles", {}).get("enabled", True):
subtitle_exts = config.get("general", {}).get("subtitles", {}).get("extensions", ".vtt,.srt,.ass,.ssa,.sub").split(",") subtitle_exts = config.get("general", {}).get("subtitles", {}).get("extensions", ".vtt,.srt,.ass,.ssa,.sub").split(",")
# Look for subtitle with same base name (e.g., movie.vtt or movie.en.vtt) parent_dir = file.parent
base_name = file.stem
found_subs = set() # Track found subtitles to avoid duplicates
# Look for subtitle files with same base name (e.g., movie.vtt or movie.en.vtt)
for ext in subtitle_exts: for ext in subtitle_exts:
ext = ext.strip() ext = ext.strip()
# Try exact match first (movie.vtt) # Try exact match first (movie.vtt)
potential_sub = file.with_suffix(ext) potential_sub = file.with_suffix(ext)
if potential_sub.exists(): if potential_sub.exists() and str(potential_sub) not in found_subs:
subtitle_file = potential_sub subtitle_files.append(potential_sub)
print(f"📝 Found subtitle: {subtitle_file.name}") found_subs.add(str(potential_sub))
logger.info(f"Found subtitle file: {subtitle_file.name}") print(f"📝 Found subtitle: {potential_sub.name}")
break logger.info(f"Found subtitle file: {potential_sub.name}")
# Try language prefix variants (movie.en.vtt, movie.eng.vtt, etc.) # Try language prefix variants (movie.en.vtt, movie.eng.vtt, movie.en.forced.srt, etc.)
# Look for files matching the pattern basename.*language*.ext # Look for all files matching the pattern basename.*ext
parent_dir = file.parent for item in sorted(parent_dir.glob(f"{base_name}.*{ext}")):
base_name = file.stem if str(item) not in found_subs:
for item in parent_dir.glob(f"{base_name}.*{ext}"): subtitle_files.append(item)
subtitle_file = item found_subs.add(str(item))
print(f"📝 Found subtitle: {subtitle_file.name}") print(f"📝 Found subtitle: {item.name}")
logger.info(f"Found subtitle file: {subtitle_file.name}") logger.info(f"Found subtitle file: {item.name}")
break
if subtitle_file:
break
try: try:
# Detect source resolution and determine target resolution # Detect source resolution and determine target resolution
@ -154,6 +179,29 @@ def process_folder(folder: Path, cq: int, transcode_mode: str, resolution: str,
src_width, src_height, explicit_resolution src_width, src_height, explicit_resolution
) )
# Auto-select encoder based on source bit depth if not explicitly specified
# (explicit encoder arg is passed in, so if user didn't specify, it's still the default)
# We need to check if encoder came from CLI or is the default
# For now, we'll always auto-detect and only skip if encoder was explicitly set
# Since we can't distinguish in the current flow, we'll add a parameter to track this
selected_encoder = encoder # Start with what was passed (may be default)
# Check source bit depth for auto-selection
source_bit_depth = get_source_bit_depth(temp_input)
# Auto-select encoder based on source bit depth
# 10-bit or higher (including 12-bit) → HEVC (supports up to 10-bit)
# 8-bit → AV1 (more efficient for 8-bit)
if source_bit_depth >= 10:
selected_encoder = "hevc"
encoder_note = "auto-selected (10+ bit source)"
else:
selected_encoder = "av1"
encoder_note = "auto-selected (8-bit source)"
print(f" Encoder: {selected_encoder} ({encoder_note})")
logger.info(f"Selected encoder: {selected_encoder} - Source bit depth: {source_bit_depth}-bit")
# Log resolution decision # Log resolution decision
if explicit_resolution: if explicit_resolution:
logger.info(f"Using explicitly specified resolution: {res_width}x{res_height}") logger.info(f"Using explicitly specified resolution: {res_width}x{res_height}")
@ -168,8 +216,16 @@ def process_folder(folder: Path, cq: int, transcode_mode: str, resolution: str,
print(f" Source {src_width}x{src_height} is at or below 1080p. Preserving resolution.") print(f" Source {src_width}x{src_height} is at or below 1080p. Preserving resolution.")
logger.info(f"Source {src_width}x{src_height} (<=1080p). Preserving source resolution.") logger.info(f"Source {src_width}x{src_height} (<=1080p). Preserving source resolution.")
# Set CQ based on content type and target resolution # Set CQ based on content type, target resolution, and encoder
content_cq = config["encode"]["cq"].get(f"tv_{target_resolution}" if is_tv else f"movie_{target_resolution}", 32) if is_anime:
cq_key = f"anime_{target_resolution}"
elif is_tv:
cq_key = f"tv_{target_resolution}"
else:
cq_key = f"movie_{target_resolution}"
# Look up CQ from encoder-specific section
encoder_cq_config = config["encode"]["cq"].get(selected_encoder, {})
content_cq = encoder_cq_config.get(cq_key, 32)
file_cq = cq if cq is not None else content_cq file_cq = cq if cq is not None else content_cq
# Always output as .mkv (AV1 video codec) with [EHX] suffix # Always output as .mkv (AV1 video codec) with [EHX] suffix
@ -185,9 +241,21 @@ def process_folder(folder: Path, cq: int, transcode_mode: str, resolution: str,
# Attempt encoding # Attempt encoding
try: try:
# Determine audio_filter config (CLI arg overrides config file)
# --filter-audio flag means: show interactive prompt
if filter_audio:
audio_filter_config = {"enabled": True, "interactive": True}
# If --audio-select provided, skip interactive and use pre-selected streams
if audio_select:
audio_filter_config["preselected"] = audio_select
else:
# Use config file setting (if present)
audio_filter_config = config.get("general", {}).get("audio_filter", {})
orig_size, out_size, reduction_ratio = run_ffmpeg( orig_size, out_size, reduction_ratio = run_ffmpeg(
temp_input, temp_output, file_cq, res_width, res_height, src_width, src_height, temp_input, temp_output, file_cq, res_width, res_height, src_width, src_height,
filter_flags, audio_config, method, bitrate_config, subtitle_file, audio_language filter_flags, audio_config, method, bitrate_config, selected_encoder, subtitle_files, audio_language,
audio_filter_config, test_mode, strip_all_titles
) )
# Check if encode met size target # Check if encode met size target
@ -214,7 +282,7 @@ def process_folder(folder: Path, cq: int, transcode_mode: str, resolution: str,
'target_resolution': target_resolution, 'target_resolution': target_resolution,
'file_cq': file_cq, 'file_cq': file_cq,
'is_tv': is_tv, 'is_tv': is_tv,
'subtitle_file': subtitle_file 'subtitle_files': subtitle_files
}) })
consecutive_failures += 1 consecutive_failures += 1
if consecutive_failures >= max_consecutive: if consecutive_failures >= max_consecutive:
@ -258,7 +326,7 @@ def process_folder(folder: Path, cq: int, transcode_mode: str, resolution: str,
'target_resolution': target_resolution, 'target_resolution': target_resolution,
'file_cq': file_cq, 'file_cq': file_cq,
'is_tv': is_tv, 'is_tv': is_tv,
'subtitle_file': subtitle_file 'subtitle_files': subtitle_files
}) })
consecutive_failures += 1 consecutive_failures += 1
if consecutive_failures >= max_consecutive: if consecutive_failures >= max_consecutive:
@ -283,7 +351,7 @@ def process_folder(folder: Path, cq: int, transcode_mode: str, resolution: str,
_save_successful_encoding( _save_successful_encoding(
file, temp_input, temp_output, orig_size, out_size, file, temp_input, temp_output, orig_size, out_size,
reduction_ratio, method, src_width, src_height, res_width, res_height, reduction_ratio, method, src_width, src_height, res_width, res_height,
file_cq, tracker_file, folder, is_tv, config, test_mode, subtitle_file file_cq, tracker_file, folder, is_tv, suffix, config, test_mode, subtitle_files
) )
# In test mode, stop after first successful file # In test mode, stop after first successful file
@ -335,8 +403,8 @@ def process_folder(folder: Path, cq: int, transcode_mode: str, resolution: str,
temp_input, temp_output, file_data['file_cq'], temp_input, temp_output, file_data['file_cq'],
file_data['res_width'], file_data['res_height'], file_data['res_width'], file_data['res_height'],
file_data['src_width'], file_data['src_height'], file_data['src_width'], file_data['src_height'],
filter_flags, audio_config, "Bitrate", bitrate_config, filter_flags, audio_config, "Bitrate", bitrate_config, selected_encoder,
file_data.get('subtitle_file'), audio_language file_data.get('subtitle_files'), audio_language, None, test_mode, strip_all_titles
) )
# Check if bitrate also failed # Check if bitrate also failed
@ -358,8 +426,8 @@ def process_folder(folder: Path, cq: int, transcode_mode: str, resolution: str,
file_data['src_width'], file_data['src_height'], file_data['src_width'], file_data['src_height'],
file_data['res_width'], file_data['res_height'], file_data['res_width'], file_data['res_height'],
file_data['file_cq'], tracker_file, file_data['file_cq'], tracker_file,
folder, file_data['is_tv'], config, False, folder, file_data['is_tv'], suffix, config, False,
file_data.get('subtitle_file') file_data.get('subtitle_files')
) )
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
@ -390,7 +458,7 @@ def process_folder(folder: Path, cq: int, transcode_mode: str, resolution: str,
def _save_successful_encoding(file, temp_input, temp_output, orig_size, out_size, def _save_successful_encoding(file, temp_input, temp_output, orig_size, out_size,
reduction_ratio, method, src_width, src_height, res_width, res_height, reduction_ratio, method, src_width, src_height, res_width, res_height,
file_cq, tracker_file, folder, is_tv, config=None, test_mode=False, subtitle_file=None): file_cq, tracker_file, folder, is_tv, suffix, config=None, test_mode=False, subtitle_files=None):
"""Helper function to save successfully encoded files with [EHX] tag and clean up subtitle files.""" """Helper function to save successfully encoded files with [EHX] tag and clean up subtitle files."""
# In test mode, show ratio and skip file move/cleanup # In test mode, show ratio and skip file move/cleanup
@ -411,13 +479,24 @@ def _save_successful_encoding(file, temp_input, temp_output, orig_size, out_size
logger.info(f"TEST MODE - File: {file.name} | Ratio: {percentage}% | Method: {method}") logger.info(f"TEST MODE - File: {file.name} | Ratio: {percentage}% | Method: {method}")
return return
dest_file = file.parent / temp_output.name # Check if file is in a Featurettes folder - if so, remove suffix from destination filename
folder_parts = [p.lower() for p in file.parent.parts]
is_featurette = "featurettes" in folder_parts
if is_featurette:
# Remove suffix from temp_output.name for Featurettes
output_name = temp_output.name
if suffix in output_name:
output_name = output_name.replace(suffix, "")
dest_file = file.parent / output_name
else:
dest_file = file.parent / temp_output.name
shutil.move(temp_output, dest_file) shutil.move(temp_output, dest_file)
print(f"🚚 Moved {temp_output.name}{dest_file.name}") print(f"🚚 Moved {temp_output.name}{dest_file.name}")
logger.info(f"Moved {temp_output.name}{dest_file.name}") logger.info(f"Moved {temp_output.name}{dest_file.name}")
# Classify file type based on folder # Classify file type based on folder (folder_parts already defined earlier)
folder_parts = [p.lower() for p in folder.parts]
if "tv" in folder_parts: if "tv" in folder_parts:
f_type = "tv" f_type = "tv"
tv_index = folder_parts.index("tv") tv_index = folder_parts.index("tv")
@ -462,17 +541,24 @@ def _save_successful_encoding(file, temp_input, temp_output, orig_size, out_size
try: try:
temp_input.unlink() temp_input.unlink()
file.unlink()
logger.info(f"Deleted original and processing copy for {file.name}")
# Clean up subtitle file if it was embedded # Only delete original file if NOT in Featurettes folder (Featurettes are re-encoded in place)
if subtitle_file and subtitle_file.exists(): if not is_featurette:
try: file.unlink()
subtitle_file.unlink() logger.info(f"Deleted original and processing copy for {file.name}")
print(f"🗑️ Removed embedded subtitle: {subtitle_file.name}") else:
logger.info(f"Removed embedded subtitle: {subtitle_file.name}") logger.info(f"Featurettes file preserved at origin: {file.name}")
except Exception as e:
logger.warning(f"Could not delete subtitle file {subtitle_file.name}: {e}") # Clean up subtitle files if they exist
if subtitle_files:
for sub_file in subtitle_files:
if sub_file.exists():
try:
sub_file.unlink()
print(f"🗑️ Removed subtitle: {sub_file.name}")
logger.info(f"Removed subtitle: {sub_file.name}")
except Exception as e:
logger.warning(f"Could not delete subtitle file {sub_file.name}: {e}")
except Exception as e: except Exception as e:
print(f"⚠️ Could not delete files: {e}") print(f"⚠️ Could not delete files: {e}")
logger.warning(f"Could not delete files: {e}") logger.warning(f"Could not delete files: {e}")

View File

@ -22,17 +22,56 @@ def get_source_resolution(input_file: Path) -> tuple:
"-of", "default=noprint_wrappers=1:nokey=1:noprint_wrappers=1", "-of", "default=noprint_wrappers=1:nokey=1:noprint_wrappers=1",
str(input_file) str(input_file)
] ]
result = subprocess.run(cmd, capture_output=True, text=True, check=True) result = subprocess.run(cmd, capture_output=True, text=True, encoding='utf-8', errors='ignore', check=False)
lines = result.stdout.strip().split("\n") if result.stdout:
width = int(lines[0]) if len(lines) > 0 else 1920 lines = result.stdout.strip().split("\n")
height = int(lines[1]) if len(lines) > 1 else 1080 width = int(lines[0]) if len(lines) > 0 and lines[0].strip() else 1920
logger.info(f"Source resolution detected: {width}x{height}") height = int(lines[1]) if len(lines) > 1 and lines[1].strip() else 1080
return (width, height) logger.info(f"Source resolution detected: {width}x{height}")
return (width, height)
else:
logger.warning(f"ffprobe returned no output for {input_file.name}. Defaulting to 1920x1080")
return (1920, 1080)
except Exception as e: except Exception as e:
logger.warning(f"Failed to detect source resolution: {e}. Defaulting to 1920x1080") logger.warning(f"Failed to detect source resolution: {e}. Defaulting to 1920x1080")
return (1920, 1080) return (1920, 1080)
def get_source_bit_depth(input_file: Path) -> int:
"""
Detect source video bit depth (8, 10, or 12).
Returns: 12, 10, or 8 (default)
"""
try:
cmd = [
"ffprobe", "-v", "error",
"-select_streams", "v:0",
"-show_entries", "stream=pix_fmt",
"-of", "default=noprint_wrappers=1:nokey=1",
str(input_file)
]
result = subprocess.run(cmd, capture_output=True, text=True, encoding='utf-8', errors='ignore', check=False)
if result.stdout:
pix_fmt = result.stdout.strip().lower()
# Check for 12-bit indicators first
if any(x in pix_fmt for x in ["12le", "12be"]):
logger.info(f"Source bit depth detected: 12-bit ({pix_fmt})")
return 12
# Check for 10-bit indicators
elif any(x in pix_fmt for x in ["10le", "10be", "p010", "yuv420p10"]):
logger.info(f"Source bit depth detected: 10-bit ({pix_fmt})")
return 10
else:
logger.info(f"Source bit depth detected: 8-bit ({pix_fmt})")
return 8
else:
logger.debug(f"Could not detect bit depth for {input_file.name}. Defaulting to 8-bit")
return 8
except Exception as e:
logger.warning(f"Failed to detect source bit depth: {e}. Defaulting to 8-bit")
return 8
def determine_target_resolution(src_width: int, src_height: int, explicit_resolution: str = None) -> tuple: def determine_target_resolution(src_width: int, src_height: int, explicit_resolution: str = None) -> tuple:
""" """
Determine target resolution based on source and explicit override. Determine target resolution based on source and explicit override.

File diff suppressed because it is too large Load Diff

View File

@ -31,3 +31,33 @@
2026-01-01 01:25:05 | Supernatural - S07E17 - The Born-Again Identity x265 AC3 Bluray-1080p HiQVE.mkv | CQ error: Command '['ffmpeg', '-y', '-i', 'C:\\Users\\Tyler\\Documents\\GitHub\\conversion_project\\processing 2026-01-01 01:25:05 | Supernatural - S07E17 - The Born-Again Identity x265 AC3 Bluray-1080p HiQVE.mkv | CQ error: Command '['ffmpeg', '-y', '-i', 'C:\\Users\\Tyler\\Documents\\GitHub\\conversion_project\\processing
2026-01-01 13:17:15 | The Office (US) - S08E04 - Garden Party x265 AAC Bluray-1080p Silence.mkv | CQ failed: Size threshold not met (122.2%) 2026-01-01 13:17:15 | The Office (US) - S08E04 - Garden Party x265 AAC Bluray-1080p Silence.mkv | CQ failed: Size threshold not met (122.2%)
2026-01-01 13:22:48 | The Office (US) - S08E04 - Garden Party x265 AAC Bluray-1080p Silence.mkv | CQ failed: Size threshold not met (101.3%) 2026-01-01 13:22:48 | The Office (US) - S08E04 - Garden Party x265 AAC Bluray-1080p Silence.mkv | CQ failed: Size threshold not met (101.3%)
2026-01-01 20:53:58 | ._Superman (2025) x265 EAC3 7.1 Bluray-1080p Ghost.mkv | CQ error: Command '['ffmpeg', '-y', '-i', 'C:\\Users\\Tyler\\Documents\\GitHub\\conversion_project\\processing
2026-01-01 20:55:56 | [sam] Vanitas no Carte - 02 [BD 1080p FLAC] [8822B4BC].mkv | Unexpected error: too many values to unpack (expected 5)
2026-01-01 20:56:12 | [sam] Vanitas no Carte - 03 [BD 1080p FLAC] [BDE63D2B].mkv | Unexpected error: too many values to unpack (expected 5)
2026-01-01 21:00:10 | [sam] Vanitas no Carte - 02 [BD 1080p FLAC] [8822B4BC].mkv | Unexpected error: too many values to unpack (expected 5)
2026-01-01 22:51:03 | ._Superman (2025) x265 EAC3 7.1 Bluray-1080p Ghost.mkv | CQ error: Command '['ffmpeg', '-y', '-i', 'C:\\Users\\Tyler\\Documents\\GitHub\\conversion_project\\processing
2026-01-01 22:51:21 | A New Era DC Takes Off.mkv | CQ failed: Size threshold not met (81.8%)
2026-01-01 22:51:37 | Adventures in the Making of “Superman”.mkv | Unexpected error: 'NoneType' object has no attribute 'split'
2026-01-01 22:53:54 | ._Superman (2025) x265 EAC3 7.1 Bluray-1080p Ghost.mkv | CQ error: Command '['ffmpeg', '-y', '-i', 'C:\\Users\\Tyler\\Documents\\GitHub\\conversion_project\\processing
2026-01-01 22:54:13 | A New Era DC Takes Off.mkv | CQ failed: Size threshold not met (81.8%)
2026-01-01 22:57:40 | ._Superman (2025) x265 EAC3 7.1 Bluray-1080p Ghost.mkv | CQ error: Command '['ffmpeg', '-y', '-i', 'C:\\Users\\Tyler\\Documents\\GitHub\\conversion_project\\processing
2026-01-01 22:58:01 | A New Era DC Takes Off.mkv | Unexpected error: name 'suffix' is not defined
2026-01-08 10:37:48 | According to Plan.mkv | CQ failed: Size threshold not met (94.3%)
2026-01-08 10:37:56 | Bloopers of the Caribbean.mkv | CQ failed: Size threshold not met (122.9%)
2026-01-08 10:39:01 | Captain Jack - From Head to Toe.mkv | CQ failed: Size threshold not met (110.9%)
2026-01-08 11:46:19 | Anatomy of a Scene - The Maelstrom.mkv | CQ failed: Size threshold not met (202.4%)
2026-01-08 11:46:59 | Bloopers of the Caribbean.mkv | CQ failed: Size threshold not met (107.0%)
2026-01-08 11:50:26 | Deleted & Extended Scenes.mkv | CQ failed: Size threshold not met (116.3%)
2026-01-08 13:38:12 | An Epic at Sea.mkv | CQ failed: Size threshold not met (85.1%)
2026-01-08 13:38:27 | Becoming Barbossa.mkv | CQ failed: Size threshold not met (93.0%)
2026-01-08 13:38:47 | Becoming Captain Jack.mkv | CQ failed: Size threshold not met (95.2%)
2026-01-08 13:56:34 | Bloopers of the Caribbean.mkv | CQ failed: Size threshold not met (103.5%)
2026-01-08 14:04:01 | Dead Men Tell No Tales - The Making of a New Adventure.mkv | CQ failed: Size threshold not met (156.6%)
2026-01-08 14:22:53 | Bloopers of the Caribbean.mkv | CQ failed: Size threshold not met (116.2%)
2026-01-08 14:24:16 | Deleted and Extended Scenes.mkv | CQ failed: Size threshold not met (115.3%)
2026-01-08 14:26:55 | Easter Eggs.mkv | CQ failed: Size threshold not met (227.9%)
2026-01-08 16:15:19 | Trailer [kr].mkv | CQ failed: Size threshold not met (106.3%)
2026-01-08 18:49:04 | The Ultimate Villain.mkv | CQ failed: Size threshold not met (85.9%)
2026-01-10 09:27:28 | 2.5.Dimensional.Seduction.2024.S01E01.REPACK2.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold.mkv | Unexpected error: name 'subtitle_file' is not defined
2026-01-10 09:39:03 | 2.5.Dimensional.Seduction.2024.S01E01.REPACK2.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold.mkv | Unexpected error: name 'subtitle_file' is not defined
2026-01-10 09:44:37 | 2.5.Dimensional.Seduction.2024.S01E01.REPACK2.BDRip-1080p.x265.FLAC.EAC3.Dual.Audio-Freehold.mkv | Unexpected error: name 'subtitle_file' is not defined

27
main.py
View File

@ -89,10 +89,10 @@ def main():
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=""" epilog="""
Examples: Examples:
%(prog)s "C:\\Videos\\Movies" # Smart mode (preserve resolution, 4K->1080p) %(prog)s "C:\\Videos\\Movies" # CQ mode (preserve resolution, 4K->1080p)
%(prog)s "C:\\Videos\\TV" --r 720 --m bitrate # Force 720p, bitrate mode %(prog)s "C:\\Videos\\TV" --r 720 --m bitrate # Force 720p, bitrate mode
%(prog)s "C:\\Videos\\Anime" --cq 28 --r 1080 # Force 1080p, CQ=28 %(prog)s "C:\\Videos\\Anime" --cq 28 --r 1080 # Force 1080p, CQ=28
%(prog)s "C:\\Videos\\Low-Res" --r 480 # Force 480p for low-res content %(prog)s "C:\\Videos\\Low-Res" --m compression --r 480 # Force 480p, try CQ then bitrate for compression
""" """
) )
@ -100,8 +100,13 @@ Examples:
parser.add_argument("--cq", type=int, help="Override default CQ value") parser.add_argument("--cq", type=int, help="Override default CQ value")
parser.add_argument( parser.add_argument(
"--m", "--mode", dest="transcode_mode", default="cq", "--m", "--mode", dest="transcode_mode", default="cq",
choices=["cq", "bitrate"], choices=["cq", "bitrate", "compression"],
help="Encode mode: CQ (constant quality) or Bitrate mode" help="Encode mode: 'cq' (constant quality only), 'bitrate' (bitrate only), or 'compression' (try CQ then bitrate fallback)"
)
parser.add_argument(
"--encoder", dest="encoder", default="hevc",
choices=["hevc", "av1"],
help="Video encoder: 'hevc' for HEVC NVENC 10-bit (default), 'av1' for AV1 NVENC 8-bit"
) )
parser.add_argument( parser.add_argument(
"--r", "--resolution", dest="resolution", default=None, "--r", "--resolution", dest="resolution", default=None,
@ -116,6 +121,18 @@ Examples:
"--language", dest="audio_language", default=None, "--language", dest="audio_language", default=None,
help="Tag audio streams with language code (e.g., eng, spa, fra). If not set, audio language is unchanged" help="Tag audio streams with language code (e.g., eng, spa, fra). If not set, audio language is unchanged"
) )
parser.add_argument(
"--filter-audio", dest="filter_audio", default=None, action="store_true",
help="Interactive audio selection: show audio streams and let user choose which to keep (overrides config setting)"
)
parser.add_argument(
"--audio-select", dest="audio_select", default=None,
help="Pre-select audio streams to keep (comma-separated, e.g., 1,2). Skips interactive prompt. Requires --filter-audio"
)
parser.add_argument(
"--strip-all-titles", dest="strip_all_titles", default=False, action="store_true",
help="Strip title metadata from all audio tracks (default: False)"
)
args = parser.parse_args() args = parser.parse_args()
# Load configuration # Load configuration
@ -132,7 +149,7 @@ Examples:
return return
# Process folder # Process folder
process_folder(folder, args.cq, args.transcode_mode, args.resolution, config, TRACKER_FILE, args.test_mode, args.audio_language) process_folder(folder, args.cq, args.transcode_mode, args.resolution, config, TRACKER_FILE, args.test_mode, args.audio_language, args.filter_audio, args.audio_select, args.encoder, args.strip_all_titles)
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -0,0 +1,322 @@
{
"P:\\tv\\Hero Inside (2023)": 7372329680,
"P:\\tv\\Below Deck": 47516712212,
"P:\\tv\\The Penguin": 4459075060,
"P:\\tv\\Banshee (2013)": 25030541772,
"P:\\tv\\Dungeons & Dragons": 6660128393,
"P:\\tv\\Made For Love (2021)": 2211136772,
"P:\\tv\\Sirens (2025)": 4246622090,
"P:\\tv\\Landman (2024)": 35220290035,
"P:\\tv\\Last Man Standing": 49393251846,
"P:\\tv\\Alien - Earth (2025)": 2926145405,
"P:\\tv\\The Big Door Prize": 2314902686,
"P:\\tv\\Government Cheese (2025)": 15970704500,
"P:\\tv\\In the Dark (2019)": 2555891397,
"P:\\tv\\Tulsa King": 41351406080,
"P:\\tv\\Dopesick": 2571994785,
"P:\\tv\\Taylor (2025)": 2621206209,
"P:\\tv\\Star Trek Lower Decks": 33090597113,
"P:\\tv\\Face Off (2011)": 83155672195,
"P:\\tv\\Catch-22": 7113496871,
"P:\\tv\\Canada's Drag Race": 103586850759,
"P:\\tv\\Over the Garden Wall": 2937573633,
"P:\\tv\\The Traitors (US) (2023)": 48149750078,
"P:\\tv\\1923": 22125507023,
"P:\\tv\\Loki": 20082144632,
"P:\\tv\\House of the Dragon": 23959073249,
"P:\\tv\\The Trunk (2024)": 16810949304,
"P:\\tv\\The Chosen (2019)": 54241850899,
"P:\\tv\\Lucky Hank": 7336222432,
"P:\\tv\\Station Eleven": 2708694925,
"P:\\tv\\Kitchen Nightmares UK": 11563663098,
"P:\\tv\\The Good Lord Bird (2020)": 5619421375,
"P:\\tv\\Wolf Pack": 6844099384,
"P:\\tv\\Below Deck Mediterranean": 39902249615,
"P:\\tv\\The Old Man (2022)": 26139845941,
"P:\\tv\\Schitt's Creek": 9325109901,
"P:\\tv\\Mr. & Mrs. Smith (2024)": 5316681916,
"P:\\tv\\Percy Jackson and the Olympians": 3558450335,
"P:\\tv\\Firefly (2002)": 7517428895,
"P:\\tv\\Ballers": 13002096756,
"P:\\tv\\Bupkis": 13034439710,
"P:\\tv\\The Offer": 9070667475,
"P:\\tv\\Life After People (2009)": 45628647899,
"P:\\tv\\The Lord of the Rings - The Rings of Power": 12834498889,
"P:\\tv\\Paradise (2025)": 8024209737,
"P:\\tv\\Nobody Wants This": 11516933757,
"P:\\tv\\Shrinking (2023)": 17293593983,
"P:\\tv\\Hawkeye": 13524278345,
"P:\\tv\\Home Economics": 14315967074,
"P:\\tv\\Time Bandits (2024)": 6997478287,
"P:\\tv\\Lessons in Chemistry (2023)": 5485801173,
"P:\\tv\\1883": 4514294832,
"P:\\tv\\Love, Death & Robots (2019)": 8204860116,
"P:\\tv\\The Legend of Vox Machina": 25197294503,
"P:\\tv\\Harry Potter - Wizards of Baking (2024)": 23545641052,
"P:\\tv\\The Bachelor": 40368931577,
"P:\\tv\\American Horror Story": 142468660014,
"P:\\tv\\Yellowstone (2018)": 89724605866,
"P:\\tv\\St. Denis Medical (2024)": 18704263469,
"P:\\tv\\Cobra Kai": 39761471967,
"P:\\tv\\Power (2014)": 20414619656,
"P:\\tv\\The Originals (2013)": 72912846985,
"P:\\tv\\The Edge of Sleep": 1358235145,
"P:\\tv\\3 Body Problem": 11369334730,
"P:\\tv\\New Girl": 40676856398,
"P:\\tv\\Assembly Required (2021)": 5737519036,
"P:\\tv\\30 Rock (2006)": 81412969909,
"P:\\tv\\Rupauls Drag Race UK vs The World": 35504142221,
"P:\\tv\\Daredevil - Born Again (2025)": 7647367391,
"P:\\tv\\Brooklyn Nine Nine": 45722673163,
"P:\\tv\\Taskmaster - Champion of Champions": 2700754514,
"P:\\tv\\Kim's Convenience": 30475634673,
"P:\\tv\\The Office (US)": 161867626607,
"P:\\tv\\Stranger Things (2016)": 66712664909,
"P:\\tv\\Rupaul's Drag Race Vegas Revue": 2532474468,
"P:\\tv\\The Umbrella Academy": 55348092191,
"P:\\tv\\Secret Celebrity RuPaul's Drag Race": 4211193920,
"P:\\tv\\Andor (2022)": 25679584728,
"P:\\tv\\The Bondsman (2025)": 3112664353,
"P:\\tv\\Ghosts (2021)": 4574333812,
"P:\\tv\\Interior Chinatown": 3167640001,
"P:\\tv\\Selfie": 5013734266,
"P:\\tv\\Supernatural": 209274293691,
"P:\\tv\\Superman and Lois": 44881535930,
"P:\\tv\\Black Sails (2014)": 11356486450,
"P:\\tv\\Taskmaster (CA) (2022)": 2431664380,
"P:\\tv\\The Last of Us": 30545352719,
"P:\\tv\\Halo": 6961206915,
"P:\\tv\\Home Improvement 1991": 48878774505,
"P:\\tv\\Detroiters (2017)": 33750584701,
"P:\\tv\\Wildemount Wildlings (2025)": 3348907992,
"P:\\tv\\Terminator Zero": 3384699699,
"P:\\tv\\Um, Actually": 12360993522,
"P:\\tv\\The Rain (2018)": 2941174698,
"P:\\tv\\Harley Quinn": 20857796821,
"P:\\tv\\Lawmen - Bass Reeves (2023)": 5363156538,
"P:\\tv\\Parks and Recreation": 37277190974,
"P:\\tv\\Mythic Quest": 16965795814,
"P:\\tv\\Invincible (2021)": 19742824176,
"P:\\tv\\The Bear (2022)": 43665628138,
"P:\\tv\\Jentry Chau vs. the Underworld (2024)": 1406237358,
"P:\\tv\\Countdown (2025)": 8935252687,
"P:\\tv\\The Great British Bake Off": 78,
"P:\\tv\\Smartypants": 15959708127,
"P:\\tv\\Scenes from a Marriage (US)": 12493986505,
"P:\\tv\\The Franchise (2024)": 2981270395,
"P:\\tv\\Chad Powers (2025)": 2474659236,
"P:\\tv\\Doctor Who (2005)": 5820708419,
"P:\\tv\\Bad Monkey": 7767595411,
"P:\\tv\\Swimming with Sharks": 4426141798,
"P:\\tv\\English Teacher": 7603165476,
"P:\\tv\\Resident Alien (2021)": 17522605407,
"P:\\tv\\Krypton (2018)": 10875524680,
"P:\\tv\\Vikings (2013)": 194095449878,
"P:\\tv\\Arcane (2021)": 19588567847,
"P:\\tv\\Ludwig (2024)": 2670615425,
"P:\\tv\\Canada's Drag Race vs The World": 7844155647,
"P:\\tv\\BattleBots (2015)": 69,
"P:\\tv\\Abbott Elementary (2021)": 24595462535,
"P:\\tv\\Billy the Kid": 44803721006,
"P:\\tv\\Quantum Leap 2022": 8902776416,
"P:\\tv\\Obi-Wan Kenobi": 13867986923,
"P:\\tv\\Matlock (2024)": 34470939613,
"P:\\tv\\The Fall of Diddy (2025)": 2431035593,
"P:\\tv\\Kaos": 5164057710,
"P:\\tv\\Shifting Gears (2025)": 12649531141,
"P:\\tv\\Saving Hope": 33116225358,
"P:\\tv\\Gen V (2023)": 16871757804,
"P:\\tv\\Below Deck Sailing Yacht": 12706704039,
"P:\\tv\\Monarch Legacy of Monsters": 18371826949,
"P:\\tv\\High Potential": 24339309461,
"P:\\tv\\Band of Brothers (2001)": 15129362120,
"P:\\tv\\Quantum Leap (1989)": 39284023472,
"P:\\tv\\Harley and the Davidsons": 76,
"P:\\tv\\Rupaul's Drag Race All Stars": 60579323023,
"P:\\tv\\Amazing Stories (2020)": 4281304451,
"P:\\tv\\Murder She Wrote": 12095973826,
"P:\\tv\\Kitchen Nightmares US": 56092851597,
"P:\\tv\\Game Changer": 38317757866,
"P:\\tv\\Taskmaster AU": 20527610746,
"P:\\tv\\Fallout": 19686023936,
"P:\\tv\\Young Sheldon": 21714069112,
"P:\\tv\\Vice Principals (2016)": 18406955713,
"P:\\tv\\Adventuring Academy": 62196997373,
"P:\\tv\\Solar Opposites": 1138214210,
"P:\\tv\\Pok\u00e9mon Concierge (2023)": 1134616527,
"P:\\tv\\Better Call Saul": 31152560439,
"P:\\tv\\Counterpart": 4875616955,
"P:\\tv\\The Paper (2025)": 8102218176,
"P:\\tv\\Chuck": 32193192829,
"P:\\tv\\The Bachelorette": 9927266246,
"P:\\tv\\Wandavision": 10099450034,
"P:\\tv\\Pantheon": 13397374449,
"P:\\tv\\The Gilded Age": 90505242840,
"P:\\tv\\Gastronauts": 9365810750,
"P:\\tv\\American Gods (2017)": 43921706762,
"P:\\tv\\The IT Crowd (2006)": 9239572772,
"P:\\tv\\Winning Time - The Rise of the Lakers Dynasty (2022)": 37911197652,
"P:\\tv\\Monet's Slumber Party": 8253206091,
"P:\\tv\\Walker": 5492500161,
"P:\\tv\\Stargirl": 9507100884,
"P:\\tv\\House of Guinness (2025)": 5444928896,
"P:\\tv\\Father Brown": 18896564477,
"P:\\tv\\Silo (2023)": 12897630564,
"P:\\tv\\Your Honor (2020)": 25879839349,
"P:\\tv\\Welcome to Wrexham": 66664948104,
"P:\\tv\\Royal Pains (2009)": 1247586112,
"P:\\tv\\The Continental (2023)": 1920206807,
"P:\\tv\\Citadel": 2339699246,
"P:\\tv\\The 10th Kingdom (2000)": 14174589505,
"P:\\tv\\Parlor Room": 12022280605,
"P:\\tv\\Its Always Sunny in Philadelphia": 84650830434,
"P:\\tv\\Star Wars - Skeleton Crew (2024)": 2940779001,
"P:\\tv\\Rupaul's Drag Race": 57149739065,
"P:\\tv\\Only Murders in the Building (2021)": 2379838148,
"P:\\tv\\Running Man": 10279755878,
"P:\\tv\\Shetland": 18537045340,
"P:\\tv\\Adults (2025)": 6845585714,
"P:\\tv\\iCarly (2021)": 19966043984,
"P:\\tv\\Villainous (2017)": 1961793524,
"P:\\tv\\The Terminal List - Dark Wolf (2025)": 9939046560,
"P:\\tv\\Ted Lasso (2020)": 52046307136,
"P:\\tv\\Murderbot (2025)": 18338040970,
"P:\\tv\\RuPaul's Drag Race Down Under": 27454793482,
"P:\\tv\\Gravity Falls": 31900305156,
"P:\\tv\\The Santa Clauses (2022)": 6400385164,
"P:\\tv\\Marvel's The Punisher (2017)": 32242478897,
"P:\\tv\\Dracula (2020)": 2147285239,
"P:\\tv\\Extraordinary": 6934203888,
"P:\\tv\\Cyberpunk - Edgerunners (2022)": 11313875182,
"P:\\tv\\Rick and Morty": 31672318625,
"P:\\tv\\Welcome to Chippendales (2022)": 10423545837,
"P:\\tv\\Squid Game (2021)": 22082475135,
"P:\\tv\\MobLand (2025)": 6622179548,
"P:\\tv\\Taskmaster (NZ)": 71323320898,
"P:\\tv\\The Newsroom": 27756667258,
"P:\\tv\\The Pretender": 18425629462,
"P:\\tv\\Hazbin Hotel (2024)": 10906489515,
"P:\\tv\\Raised by wolves": 9720677524,
"P:\\tv\\Tomb Raider - The Legend of Lara Croft": 9341088252,
"P:\\tv\\Spartacus": 75639017886,
"P:\\tv\\Worst Cooks in America (2010)": 22063867049,
"P:\\tv\\Avenue 5": 12572813494,
"P:\\tv\\Man Down (2013)": 5077144151,
"P:\\tv\\Outlander": 27364180668,
"P:\\tv\\The Eternaut": 17178505929,
"P:\\tv\\Below Deck Down Under (2022)": 36006759742,
"P:\\tv\\Dirty Laundry": 27626331672,
"P:\\tv\\Chilling Adventures of Sabrina (2018)": 23147355371,
"P:\\tv\\The Studio (2025)": 11530554023,
"P:\\tv\\The Forsytes (2025)": 4034792830,
"P:\\tv\\Platonic (2023)": 17488146510,
"P:\\tv\\Love Island (US) (2019)": 20699120877,
"P:\\tv\\Dark Side of the Ring": 11863132534,
"P:\\tv\\The Day of the Jackal (2024)": 17787097381,
"P:\\tv\\Utopia (AU)": 8691287022,
"P:\\tv\\Sweetpea": 2706241673,
"P:\\tv\\Dateline NBC (1992)": 19267231607,
"P:\\tv\\Euphoria": 40925172559,
"P:\\tv\\The Consultant (2023)": 74,
"P:\\tv\\Titans (2018)": 31986198137,
"P:\\tv\\Taskmaster": 142193364333,
"P:\\tv\\Ink Master": 23329086486,
"P:\\tv\\Dimension 20": 557729281243,
"P:\\tv\\Continuum (2012)": 29352883496,
"P:\\tv\\South Park": 70261225261,
"P:\\tv\\Letterkenny": 63,
"P:\\tv\\Ghosts (2019)": 40703143881,
"P:\\tv\\Moon Knight": 10976093361,
"P:\\tv\\Twisted Metal (2023)": 12547412897,
"P:\\tv\\Extrapolations": 6690715385,
"P:\\tv\\Quiet On Set - The Dark Side Of Kids TV": 12191520028,
"P:\\tv\\Sh\u014dgun": 20899988683,
"P:\\tv\\Taboo (2017)": 19309841226,
"P:\\tv\\Ironheart (2025)": 3153557870,
"P:\\tv\\DOTA - Dragon's Blood (2021)": 12538510766,
"P:\\tv\\Knuckles": 2140786440,
"P:\\tv\\Shoresy": 9900029120,
"P:\\tv\\Impractical Jokers": 13357380400,
"P:\\tv\\One More Time (2024)": 6434473461,
"P:\\tv\\Crowd Control": 9644641207,
"P:\\tv\\Dimension 20's Adventuring Party": 12002285238,
"P:\\tv\\Special Ops Lioness": 9765393961,
"P:\\tv\\Ted (2024)": 3024624414,
"P:\\tv\\Mighty Nein (2025)": 6138965943,
"P:\\tv\\Citadel - Diana": 13304679453,
"P:\\tv\\Our Flag Means Death": 2107045664,
"P:\\tv\\Make Some Noise": 25555591381,
"P:\\tv\\Mayor of Kingstown (2021)": 65464041666,
"P:\\tv\\The Take": 6020370013,
"P:\\tv\\Agatha All Along": 3411637969,
"P:\\tv\\The Amazing Digital Circus (2023)": 4739070191,
"P:\\tv\\The Now": 836886747,
"P:\\tv\\Poppa\u2019s House": 13794748297,
"P:\\tv\\Married at First Sight (2014)": 30275711911,
"P:\\tv\\The Closer": 47449608535,
"P:\\tv\\Junior Taskmaster (2024)": 4133620030,
"P:\\tv\\WondLa": 1399628000,
"P:\\tv\\The Second Best Hospital in the Galaxy (2024)": 3636394169,
"P:\\tv\\Being Human (2011)": 66311454464,
"P:\\tv\\SCORPION": 54081802764,
"P:\\tv\\The Goes Wrong Show (2019)": 3676343887,
"P:\\tv\\See": 12316511887,
"P:\\tv\\Dirk Gently's Holistic Detective Agency (2016)": 11935610182,
"P:\\tv\\Tokyo Override (2024)": 3802255332,
"P:\\tv\\Peacemaker (2022)": 13199970800,
"P:\\tv\\The Falcon and The Winter Soldier (2021)": 11657055937,
"P:\\tv\\Fargo (2014)": 93247402537,
"P:\\tv\\Killer Cakes": 3673781461,
"P:\\tv\\The Mandalorian": 36487773789,
"P:\\tv\\Very Important People": 12237876110,
"P:\\tv\\Smiling Friends": 5633340834,
"P:\\tv\\Game Changers (2024)": 5880504271,
"P:\\tv\\Star Strek Strange New Worlds": 13781151928,
"P:\\tv\\Galavant": 12147863291,
"P:\\tv\\She-Hulk Attorney at Law": 10233633417,
"P:\\tv\\From Dusk Till Dawn - The Series (2014)": 5360771338,
"P:\\tv\\The Journal of the Mysterious Creatures (2019)": 92,
"P:\\tv\\Fallen (2024)": 4161867429,
"P:\\tv\\Severance": 15044806873,
"P:\\tv\\The Great (2020)": 22361386693,
"P:\\tv\\What If": 21312022582,
"P:\\tv\\Rupaul's Drag Race UK": 110914388896,
"P:\\tv\\Game Of Thrones": 119681469870,
"P:\\tv\\Belgravia - The Next Chapter": 8340040939,
"P:\\tv\\Hitmen (2020)": 12274410846,
"P:\\tv\\Haunted Hotel (2025)": 4735071992,
"P:\\tv\\The Book of Boba Fett": 12039417291,
"P:\\tv\\SAS Rogue Heroes (2022)": 10733559643,
"P:\\tv\\Dwight in Shining Armor": 75,
"P:\\tv\\Jury Duty": 8010062372,
"P:\\tv\\Son of Zorn (2016)": 6780978712,
"P:\\tv\\The Gentlemen (2024)": 5224500371,
"P:\\tv\\Schmigadoon!": 6206632733,
"P:\\tv\\The Drew Carey Show (1995)": 70,
"P:\\tv\\Fired on Mars (2023)": 3590992124,
"P:\\tv\\Black Bird (2022)": 5893929480,
"P:\\tv\\Billions": 31141419259,
"P:\\tv\\Reacher (2022)": 17521873037,
"P:\\tv\\The Morning Show": 94311701751,
"P:\\tv\\Secret Level": 2810124465,
"P:\\tv\\The Boys": 68010010167,
"P:\\tv\\Gordon Ramsay's Food Stars (2023)": 6344621632,
"P:\\tv\\Death and Other Details": 17844763765,
"P:\\tv\\Modern Family": 82788065200,
"P:\\tv\\Married... with Children (1987)": 64228823786,
"P:\\tv\\BattleBots": 61,
"P:\\tv\\Silicon Valley (2014)": 63657428121,
"P:\\tv\\Tires (2024)": 5375794389,
"P:\\tv\\Creature Commandos (2024)": 2331424358,
"P:\\tv\\Goosebumps (2023)": 8257419062,
"P:\\tv\\The Fall of the House of Usher (2023)": 16454192941,
"P:\\tv\\Passion for punchlines": 75514795,
"P:\\tv\\The Queen's Gambit": 4100494817,
"P:\\tv\\Suits LA (2025)": 22274831381,
"P:\\tv\\Dune - Prophecy": 3330003290,
"P:\\tv\\Unstable": 5444623642,
"P:\\tv\\The Split": 7970767632,
"P:\\tv\\Barry": 31934844666,
"P:\\tv\\The Dragon Dentist": 11317084093,
"P:\\tv\\Kevin Can F-k Himself": 11614889793
}

50
path_manager/config.xml Normal file
View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<config>
<general>
<processing_folder>processing</processing_folder>
<suffix> -EHX</suffix>
<extensions>.mkv,.mp4</extensions>
<ignore_tags>ehx,megusta</ignore_tags>
<reduction_ratio_threshold>0.5</reduction_ratio_threshold>
</general>
<path_mappings>
<map from="P:\tv" to="/mnt/plex/tv" />
<map from="P:\anime" to="/mnt/plex/anime" />
</path_mappings>
<encode>
<encoder default="nvenc">
<av1_nvenc preset="p7" bit_depth="8" pix_fmt="yuv420p" />
<hevc_nvenc preset="slow" bit_depth="10" pix_fmt="yuv420p10le" />
</encoder>
<cq>
<tv_1080>28</tv_1080>
<tv_720>32</tv_720>
<movie_1080>32</movie_1080>
<movie_720>34</movie_720>
</cq>
<fallback>
<bitrate_1080>1500k</bitrate_1080>
<maxrate_1080>1750k</maxrate_1080>
<bufsize_1080>2750k</bufsize_1080>
<bitrate_720>900k</bitrate_720>
<maxrate_720>1250k</maxrate_720>
<bufsize_720>1800k</bufsize_720>
</fallback>
<filters>
<default>lanczos</default>
<tv>bicubic</tv>
</filters>
</encode>
<audio>
<stereo>
<low>64000</low>
<medium>128000</medium>
<high>160000</high>
</stereo>
<multi_channel>
<low>384000</low>
<medium>512000</medium>
<high>640000</high>
</multi_channel>
</audio>
</config>

View File

@ -5,9 +5,14 @@ GUI Path Manager for Batch Video Transcoder
Allows easy browsing of folders and appending to paths.txt with encoding options. Allows easy browsing of folders and appending to paths.txt with encoding options.
""" """
import sys
from pathlib import Path
# Add parent directory to path so we can import core modules
sys.path.insert(0, str(Path(__file__).parent.parent))
import tkinter as tk import tkinter as tk
from tkinter import ttk, messagebox, filedialog from tkinter import ttk, messagebox, filedialog
from pathlib import Path
import os import os
import subprocess import subprocess
import re import re
@ -15,7 +20,7 @@ import json
from core.config_helper import load_config_xml from core.config_helper import load_config_xml
from core.logger_helper import setup_logger from core.logger_helper import setup_logger
logger = setup_logger(Path(__file__).parent / "logs") logger = setup_logger(Path(__file__).parent.parent / "logs")
class PathManagerGUI: class PathManagerGUI:
def __init__(self, root): def __init__(self, root):
@ -23,14 +28,16 @@ class PathManagerGUI:
self.root.title("Batch Transcoder - Path Manager") self.root.title("Batch Transcoder - Path Manager")
self.root.geometry("1100x700") self.root.geometry("1100x700")
# Load config # Load config (from parent directory)
config_path = Path(__file__).parent / "config.xml" config_path = Path(__file__).parent.parent / "config.xml"
self.config = load_config_xml(config_path) self.config = load_config_xml(config_path)
self.path_mappings = self.config.get("path_mappings", {}) # Convert path_mappings from list to dict for easier lookup
path_mappings_list = self.config.get("path_mappings", [])
self.path_mappings = {m["from"]: m["to"] for m in path_mappings_list} if isinstance(path_mappings_list, list) else path_mappings_list
# Paths file # Paths file (in root directory)
self.paths_file = Path(__file__).parent / "paths.txt" self.paths_file = Path(__file__).parent.parent / "paths.txt"
self.transcode_bat = Path(__file__).parent / "transcode.bat" self.transcode_bat = Path(__file__).parent.parent / "transcode.bat"
# Current selected folder # Current selected folder
self.selected_folder = None self.selected_folder = None
@ -40,7 +47,7 @@ class PathManagerGUI:
self.added_folders = set() # Folders that are in paths.txt self.added_folders = set() # Folders that are in paths.txt
# Cache for folder data - split per category # Cache for folder data - split per category
self.cache_dir = Path(__file__).parent / ".cache" self.cache_dir = Path(__file__).parent.parent / ".cache"
self.cache_dir.mkdir(exist_ok=True) self.cache_dir.mkdir(exist_ok=True)
self.folder_cache = {} # Only current category in memory: {folder_path: size} self.folder_cache = {} # Only current category in memory: {folder_path: size}
self.scan_in_progress = False self.scan_in_progress = False

View File

@ -0,0 +1,3 @@
{"timestamp": "2026-01-02T03:44:59Z", "level": "INFO", "message": "No cache file for tv", "module": "gui_path_manager", "funcName": "_load_cache", "line": 213}
{"timestamp": "2026-01-02T03:45:35Z", "level": "INFO", "message": "No cache file for tv", "module": "gui_path_manager", "funcName": "_load_cache", "line": 215}
{"timestamp": "2026-01-02T03:45:43Z", "level": "INFO", "message": "No cache file for movies", "module": "gui_path_manager", "funcName": "_load_cache", "line": 215}

View File

@ -1,11 +1,4 @@
--m cq "P:\movies\Starship Troopers (1997)" --m cq --cq 28 "P:\movies\Pirates of the Caribbean - At World's End (2007)"
--m cq "P:\movies\John Wick - Chapter 3 - Parabellum (2019)" --m cq --cq 28 "P:\movies\Pirates of the Caribbean - The Curse of the Black Pearl (2003)"
--m cq "P:\movies\John Wick - Chapter 2 (2017)" --m cq --cq 28 "P:\movies\Pirates of the Caribbean - Dead Men Tell No Tales (2017)"
--m cq "P:\movies\Belle (2021)" --m cq --cq 28 "P:\movies\Pirates of the Caribbean - On Stranger Tides (2011)"
--m cq "P:\movies\TAYLOR SWIFT THE ERAS TOUR (2023)"
--m cq "P:\movies\Ferris Bueller's Day Off (1986)"
--m cq --r 720 "P:\movies\The Baker (2023)"
--m cq "P:\movies\The Losers (2010)"
--m cq "P:\movies\Violent Night (2022)"
--m cq "P:\movies\Scott Pilgrim vs. the World (2010)"
--m cq "P:\movies\Small Soldiers (1998)"

9
paths.txt Normal file
View File

@ -0,0 +1,9 @@
"P:\movies\Ponyo (2008)"
"P:\movies\Castle in the Sky (1986)"
"P:\movies\The Secret Life of Walter Mitty (2013)"
"P:\movies\Let's Be Cops (2014)"
"P:\movies\Deadpool & Wolverine (2024)"
"P:\movies\The Secret World of Arrietty (2010)"
"P:\movies\The Irregular at Magic High School - The Girl Who Summons the Stars (2017)"
"P:\movies\The French Dispatch (2021)"
"P:\movies\John Carter (2012)"