final touches to interface to include album covers, and more
This commit is contained in:
parent
1fedcdf92b
commit
a1b0439bd0
|
@ -15,6 +15,7 @@
|
|||
"urlpattern-polyfill": "^9.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chokidar": "^3.5.3",
|
||||
"eslint": "^8.49.0",
|
||||
"eslint-plugin-lit": "^1.9.1",
|
||||
"sass": "^1.67.0",
|
||||
|
|
|
@ -1,50 +1,51 @@
|
|||
[
|
||||
{
|
||||
"title": "Late Junction",
|
||||
"details": "BBC, 2019",
|
||||
"title": "Fireside Chat",
|
||||
"details": "Mark \"Frosty\" McNeil, Red Bull Radio, 2019",
|
||||
"parent_dir": "documentaries_interviews_audio",
|
||||
"media": "-21 08_Late Junction_2019 - Meredith Monk v2 BBC"
|
||||
"media": "Fireside Chat_Mark \"Frosty\" McNeil, Red Bull Radio, 2019.mp3",
|
||||
"image": "Fireside Chat_Mark \"Frosty\" McNeil, Red Bull Radio, 2019.png"
|
||||
},
|
||||
{
|
||||
"title": "Speaking of Music",
|
||||
"details": "Meredith Monk, 1984 Part 1 of 2",
|
||||
"title": "Irene Ferchl, Bayerischer Rundfunk",
|
||||
"details": "Kulturjournal, 1986",
|
||||
"parent_dir": "documentaries_interviews_audio",
|
||||
"media": "-22 02_Speaking of Music Meredith Monk 1984 Part 1 of 2"
|
||||
},
|
||||
{
|
||||
"title": "Speaking of Music",
|
||||
"details": "Meredith Monk, 1984 Part 2 of 2",
|
||||
"parent_dir": "documentaries_interviews_audio",
|
||||
"media": "-23 03_Speaking of Music_ Meredith Monk 1984 Part 2 of 2"
|
||||
},
|
||||
{
|
||||
"title": "Interview with I Frechl-Bayn Rundfunk",
|
||||
"details": "1986",
|
||||
"parent_dir": "documentaries_interviews_audio",
|
||||
"media": "-24 04 Meredith Monk Interview with I Ferchl_Bayn Rundfunk 1986"
|
||||
},
|
||||
{
|
||||
"title": "Terry Gross Interview",
|
||||
"details": "1987",
|
||||
"parent_dir": "documentaries_interviews_audio",
|
||||
"media": "-25 05 Terry Gross interview_1987"
|
||||
},
|
||||
{
|
||||
"title": "Interview with David Garland",
|
||||
"details": "WNYC, Sacred Sundays, 2008",
|
||||
"parent_dir": "documentaries_interviews_audio",
|
||||
"media": "-26 06 WNYC Interview w_ David Garland_SacredSundays_2008"
|
||||
},
|
||||
{
|
||||
"title": "Frosty McNeil and Meredith Monk",
|
||||
"details": "Fireside Chat, Red Bull Radio",
|
||||
"parent_dir": "documentaries_interviews_audio",
|
||||
"media": "-27 07_Red Bull Radio_Fireside Chat_M frosty McNeil and MM_41119"
|
||||
"media": "Irene Ferchl, Bayerischer Rundfunk_Kulturjournal, 1986.mp3",
|
||||
"image": "Irene Ferchl, Bayerischer Rundfunk_Kulturjournal, 1986.png"
|
||||
},
|
||||
{
|
||||
"title": "Late Junction",
|
||||
"details": "BBC, 2019",
|
||||
"details": "Jennifer Lucy Allan, BBC Radio 3, 2019",
|
||||
"parent_dir": "documentaries_interviews_audio",
|
||||
"media": "-28 08_Late Junction_2019 - Meredith Monk v2 BBC"
|
||||
"media": "Late Junction_Jennifer Lucy Allan, BBC Radio 3, 2019.mp3",
|
||||
"image": "Late Junction_Jennifer Lucy Allan, BBC Radio 3, 2019.png"
|
||||
},
|
||||
{
|
||||
"title": "Sacred Sundays",
|
||||
"details": "David Garland, WNYC, 2008",
|
||||
"parent_dir": "documentaries_interviews_audio",
|
||||
"media": "Sacred Sundays_David Garland, WNYC, 2008.mp3",
|
||||
"image": "Sacred Sundays_David Garland, WNYC, 2008.png"
|
||||
},
|
||||
{
|
||||
"title": "Speaking of Music",
|
||||
"details": "Charles Amirkhanian, Other Minds, 1984. Part 1 of 2",
|
||||
"parent_dir": "documentaries_interviews_audio",
|
||||
"media": "Speaking of Music_Charles Amirkhanian, Other Minds, 1984. Part 1 of 2..mp3",
|
||||
"image": "Speaking of Music_Charles Amirkhanian, Other Minds, 1984. Part 1 of 2..png"
|
||||
},
|
||||
{
|
||||
"title": "Speaking of Music",
|
||||
"details": "Charles Amirkhanian, Other Minds, 1984. Part 2 of 2",
|
||||
"parent_dir": "documentaries_interviews_audio",
|
||||
"media": "Speaking of Music_Charles Amirkhanian, Other Minds, 1984. Part 2 of 2..mp3",
|
||||
"image": "Speaking of Music_Charles Amirkhanian, Other Minds, 1984. Part 2 of 2..png"
|
||||
},
|
||||
{
|
||||
"title": "Terry Gross",
|
||||
"details": "unedited, 1987",
|
||||
"parent_dir": "documentaries_interviews_audio",
|
||||
"media": "Terry Gross_unedited, 1987.mp3",
|
||||
"image": "Terry Gross_unedited, 1987.png"
|
||||
}
|
||||
]
|
||||
]
|
|
@ -1,92 +1,114 @@
|
|||
[
|
||||
{
|
||||
"title": "Michael Blackwood Making Dances",
|
||||
"details": "",
|
||||
"title": "4 American Composers",
|
||||
"details": "documentary by Peter Greenaway, 1983",
|
||||
"parent_dir": "documentaries_interviews_video",
|
||||
"media": "--2 MichaelBlackwoodMakingDances.m4v"
|
||||
},
|
||||
{
|
||||
"title": "ECM 1981",
|
||||
"details": "2019",
|
||||
"parent_dir": "documentaries_interviews_video",
|
||||
"media": "--3 ECM1981 Video Meredith Monk V2_2019.m4v"
|
||||
"media": "4 American Composers_documentary by Peter Greenaway, 1983.m4v",
|
||||
"image": "4 American Composers_documentary by Peter Greenaway, 1983.jpg"
|
||||
},
|
||||
{
|
||||
"title": "Andere Avantgarde",
|
||||
"details": "TV Interview 1982",
|
||||
"details": "television documentary by Peter Greenaway, 1983",
|
||||
"parent_dir": "documentaries_interviews_video",
|
||||
"media": "--4 Meredith Monk_Andere Avantgarde_TV Interview_1982_.m4v"
|
||||
},
|
||||
{
|
||||
"title": "New Sounds for a New World",
|
||||
"details": "1982",
|
||||
"parent_dir": "documentaries_interviews_video",
|
||||
"media": "--5 New Sounds for a New World_1982.m4v"
|
||||
},
|
||||
{
|
||||
"title": "Four American Composers",
|
||||
"details": "PeterGreenaway",
|
||||
"parent_dir": "documentaries_interviews_video",
|
||||
"media": "--6 Four American Composers_Peter Greenaway.m4v"
|
||||
"media": "Andere Avantgarde_television documentary by Peter Greenaway, 1983.m4v",
|
||||
"image": "Andere Avantgarde_television documentary by Peter Greenaway, 1983.jpg"
|
||||
},
|
||||
{
|
||||
"title": "BBC Late Show",
|
||||
"details": "",
|
||||
"details": "television interview, 1991",
|
||||
"parent_dir": "documentaries_interviews_video",
|
||||
"media": "--7 bbc_late_show (Original).m4v"
|
||||
"media": "BBC Late Show_television interview, 1991.m4v",
|
||||
"image": "BBC Late Show_television interview, 1991.jpg"
|
||||
},
|
||||
{
|
||||
"title": "Documentary by Sidsel Mundal",
|
||||
"details": "Norwegian Television, 1994",
|
||||
"title": "Coffee and Composition",
|
||||
"details": "Meredith Monk and Robert Kyr, online, 2021",
|
||||
"parent_dir": "documentaries_interviews_video",
|
||||
"media": "--8 1994 documentary by Sidsel Mundal_for Norwegian Telev.m4v"
|
||||
"media": "Coffee and Composition_Meredith Monk and Robert Kyr, online, 2021.m4v",
|
||||
"image": "Coffee and Composition_Meredith Monk and Robert Kyr, online, 2021.jpg"
|
||||
},
|
||||
{
|
||||
"title": "Television Documentary",
|
||||
"details": "Polish Television, 1995",
|
||||
"title": "Dorothy and Lillian Gish Award",
|
||||
"details": "portrait interview with Meredith Monk, 2017",
|
||||
"parent_dir": "documentaries_interviews_video",
|
||||
"media": "--9 Meredith Monk - Polish Television Documentary (1995).m4v"
|
||||
"media": "Dorothy and Lillian Gish Award_portrait interview with Meredith Monk, 2017.m4v",
|
||||
"image": "Dorothy and Lillian Gish Award_portrait interview with Meredith Monk, 2017.jpg"
|
||||
},
|
||||
{
|
||||
"title": "Inner Voice",
|
||||
"details": "",
|
||||
"title": "ECM 50 | 1981 Meredith Monk",
|
||||
"details": "documentary by Ingo Berhman for ECM Records' 50th Anniversary, 2019",
|
||||
"parent_dir": "documentaries_interviews_video",
|
||||
"media": "-12 MeredithMonk_Inner Voice.m4v"
|
||||
"media": "ECM 50 | 1981 Meredith Monk_documentary by Ingo Berhman for ECM Records' 50th Anniversary, 2019.m4v",
|
||||
"image": "ECM 50 | 1981 Meredith Monk_documentary by Ingo Berhman for ECM Records' 50th Anniversary, 2019.jpg"
|
||||
},
|
||||
{
|
||||
"title": "Lecutre Performance",
|
||||
"details": "Bennington College, 11 March 2011",
|
||||
"title": "Girlchild Diary",
|
||||
"details": "documentary on Education of the Girlchild, ed. Joëlle Schon, 2015",
|
||||
"parent_dir": "documentaries_interviews_video",
|
||||
"media": "-13 Bennington College lecture performance 3.11.11.m4v"
|
||||
"media": "Girlchild Diary_documentary on Education of the Girlchild, ed. Joëlle Schon, 2015.m4v",
|
||||
"image": "Girlchild Diary_documentary on Education of the Girlchild, ed. Joëlle Schon, 2015.jpg"
|
||||
},
|
||||
{
|
||||
"title": "",
|
||||
"title": "MMonk",
|
||||
"details": "TheSoulsMessenger",
|
||||
"parent_dir": "documentaries_interviews_video",
|
||||
"media": "-14 MMonk_TheSoulsMessenger_Lublin_2012.m4v"
|
||||
"media": "MMonk_TheSoulsMessenger_Lublin_2012.m4v",
|
||||
"image": "MMonk_TheSoulsMessenger_Lublin_2012.jpg"
|
||||
},
|
||||
{
|
||||
"title": "",
|
||||
"title": "Making Dances",
|
||||
"details": "documentary by Michael Blackwood, 1980",
|
||||
"parent_dir": "documentaries_interviews_video",
|
||||
"media": "-15 Girlchild Diary_61116.m4v"
|
||||
"media": "Making Dances_documentary by Michael Blackwood, 1980.m4v",
|
||||
"image": "Making Dances_documentary by Michael Blackwood, 1980.jpg"
|
||||
},
|
||||
{
|
||||
"title": "",
|
||||
"title": "Meredith Monk and Adam Shatz",
|
||||
"details": "conversation on Book of Days, online, 2020",
|
||||
"parent_dir": "documentaries_interviews_video",
|
||||
"media": "-16 Q2 Spaces_Meredith Monk_2014.m4v"
|
||||
"media": "Meredith Monk and Adam Shatz_conversation on Book of Days, online, 2020.m4v",
|
||||
"image": "Meredith Monk and Adam Shatz_conversation on Book of Days, online, 2020.jpg"
|
||||
},
|
||||
{
|
||||
"title": "",
|
||||
"title": "Meredith Monk lecture",
|
||||
"details": "Bennington College, Vermont, 2011",
|
||||
"parent_dir": "documentaries_interviews_video",
|
||||
"media": "-17 Gish Prize Ceremony Camera A.m4v"
|
||||
"media": "Meredith Monk lecture_Bennington College, Vermont, 2011.m4v",
|
||||
"image": "Meredith Monk lecture_Bennington College, Vermont, 2011.jpg"
|
||||
},
|
||||
{
|
||||
"title": "",
|
||||
"title": "Meredith Monk: Inner Voice",
|
||||
"details": "documentary by Babeth M. VanLoo, Buddhist Broadcasting Foundation, 2009",
|
||||
"parent_dir": "documentaries_interviews_video",
|
||||
"media": "-18 MM and Adam Shatz - Book of Days conversation_2020.m4v"
|
||||
"media": "Meredith Monk: Inner Voice_documentary by Babeth M. VanLoo, Buddhist Broadcasting Foundation, 2009.m4v",
|
||||
"image": "Meredith Monk: Inner Voice_documentary by Babeth M. VanLoo, Buddhist Broadcasting Foundation, 2009.jpg"
|
||||
},
|
||||
{
|
||||
"title": "",
|
||||
"title": "Meredith Monk",
|
||||
"details": "documentary by Sidsel Mundal for Norwegian Television, 1994",
|
||||
"parent_dir": "documentaries_interviews_video",
|
||||
"media": "-19 Coffee and Composition with Meredith Monk_2021.m4v"
|
||||
"media": "Meredith Monk_documentary by Sidsel Mundal for Norwegian Television, 1994.m4v",
|
||||
"image": "Meredith Monk_documentary by Sidsel Mundal for Norwegian Television, 1994.jpg"
|
||||
},
|
||||
{
|
||||
"title": "Meredith",
|
||||
"details": "documentary by Mariusz Grzegorzeki for Polish Television, 1995",
|
||||
"parent_dir": "documentaries_interviews_video",
|
||||
"media": "Meredith_documentary by Mariusz Grzegorzeki for Polish Television, 1995.m4v",
|
||||
"image": "Meredith_documentary by Mariusz Grzegorzeki for Polish Television, 1995.jpg"
|
||||
},
|
||||
{
|
||||
"title": "Neue Töne aus der Neuen Welt",
|
||||
"details": "(New Sounds for a New World) documentary by Birgitta Ashoff for German Telelvision (in German), 1983",
|
||||
"parent_dir": "documentaries_interviews_video",
|
||||
"media": "Neue Töne aus der Neuen Welt_(New Sounds for a New World) documentary by Birgitta Ashoff for German Telelvision (in German), 1983.m4v",
|
||||
"image": "Neue Töne aus der Neuen Welt_(New Sounds for a New World) documentary by Birgitta Ashoff for German Telelvision (in German), 1983.jpg"
|
||||
},
|
||||
{
|
||||
"title": "Q2 Spaces: Meredith Monk",
|
||||
"details": "documentary, 2014",
|
||||
"parent_dir": "documentaries_interviews_video",
|
||||
"media": "Q2 Spaces: Meredith Monk_documentary, 2014.m4v",
|
||||
"image": "Q2 Spaces: Meredith Monk_documentary, 2014.jpg"
|
||||
}
|
||||
]
|
||||
]
|
|
@ -1,27 +1,44 @@
|
|||
[
|
||||
{
|
||||
"title": "",
|
||||
"parent_dir": "films",
|
||||
"media": "_72 01 16_Millimeter_Earrings_1980_Color_IN_HD_23-98_ProRes4444_Pillar Scan GOOD copy v4 2023 0812.m4v"
|
||||
"title": "16 Millimeter Earrings",
|
||||
"details": "Robert S. Withers, 1979",
|
||||
"parent_dir": "Films",
|
||||
"media": "16 Millimeter Earrings_Robert S. Withers, 1979.m4v",
|
||||
"image": "16 Millimeter Earrings_Robert S. Withers, 1979.jpg"
|
||||
},
|
||||
{
|
||||
"title": "",
|
||||
"parent_dir": "films",
|
||||
"media": "_74 Ellis Island.m4v"
|
||||
"title": "Book of Days",
|
||||
"details": "Meredith Monk, 1988",
|
||||
"parent_dir": "Films",
|
||||
"media": "Book of Days_Meredith Monk, 1988.m4v",
|
||||
"image": "Book of Days_Meredith Monk, 1988.jpg"
|
||||
},
|
||||
{
|
||||
"title": "",
|
||||
"parent_dir": "films",
|
||||
"media": "_75 Book of Days.m4v"
|
||||
"title": "Ellis Island",
|
||||
"details": "Meredith Monk and Bob Rosen, 1981",
|
||||
"parent_dir": "Films",
|
||||
"media": "Ellis Island_Meredith Monk and Bob Rosen, 1981.m4v",
|
||||
"image": "Ellis Island_Meredith Monk and Bob Rosen, 1981.jpg"
|
||||
},
|
||||
{
|
||||
"title": "",
|
||||
"parent_dir": "films",
|
||||
"media": "_76 1982 Paris KTCA (full).m4v"
|
||||
"title": "Paris",
|
||||
"details": "Meredith Monk and Ping Chong, 1982",
|
||||
"parent_dir": "Films",
|
||||
"media": "Paris_Meredith Monk and Ping Chong, 1982.m4v",
|
||||
"image": "Paris_Meredith Monk and Ping Chong, 1982.jpg"
|
||||
},
|
||||
{
|
||||
"title": "",
|
||||
"parent_dir": "films",
|
||||
"media": "_77 TurtleDreams(Waltz)_Stereo_Tranfer1inchApril2018.m4v"
|
||||
"title": "Quarry",
|
||||
"details": "1977",
|
||||
"parent_dir": "Films",
|
||||
"media": "Quarry_1977.m4v",
|
||||
"image": "Quarry_1977.jpg"
|
||||
},
|
||||
{
|
||||
"title": "Turtle Dreams (Waltz)",
|
||||
"details": "Meredith Monk, 1983",
|
||||
"parent_dir": "Films",
|
||||
"media": "Turtle Dreams (Waltz)_Meredith Monk, 1983.m4v",
|
||||
"image": "Turtle Dreams (Waltz)_Meredith Monk, 1983.jpg"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
@ -1,18 +1 @@
|
|||
[
|
||||
{
|
||||
"title": "Photo One",
|
||||
"media": "photo_one.jpg"
|
||||
},
|
||||
{
|
||||
"title": "Photo Two",
|
||||
"media": "photo_two.jpg"
|
||||
},
|
||||
{
|
||||
"title": "Photo Three",
|
||||
"media": "photo_three.jpg"
|
||||
},
|
||||
{
|
||||
"title": "Photo Four",
|
||||
"media": "photo_four.jpg"
|
||||
}
|
||||
]
|
||||
[]
|
File diff suppressed because it is too large
Load Diff
|
@ -1,8 +1 @@
|
|||
[
|
||||
{
|
||||
"title": "",
|
||||
"parent_dir": "music_sound_unpublished",
|
||||
"media": "no content recieved",
|
||||
"tracks": []
|
||||
}
|
||||
]
|
||||
[]
|
||||
|
|
|
@ -1,184 +1,510 @@
|
|||
[
|
||||
{
|
||||
"title": "",
|
||||
"title": "Beginnings",
|
||||
"details": "Tzadik, 2009",
|
||||
"parent_dir": "music_sound_various",
|
||||
"media": "MONK MIX Remixes and Interpretations of Music by Meredith Monk CD1",
|
||||
"media": "Beginnings_Tzadik, 2009",
|
||||
"image": "Beginnings_Tzadik, 2009.jpg",
|
||||
"album": true,
|
||||
"tracks": [
|
||||
"01 Gotham Lullaby (Featuring Björk With The Brodsky Quartet).mp3",
|
||||
"02 Caldera Chimera (Featuring Gabriel Prokofiev Remix).mp3",
|
||||
"03 Click Song #1 (Featuring Don Byron).mp3",
|
||||
"04 Double Fiesta (Featuring Meredith Monk & Bang On A Can).mp3",
|
||||
"05 Astronaut Anthem (Featuring Sakamoto Remix).mp3",
|
||||
"06 Shaking (Featuring Lukas Ligeti) [Pyrolator Remix].mp3",
|
||||
"07 Last Song (Featuring Caetano Veloso).mp3",
|
||||
"08 Fat Stream (Featuring Nico_s Piano Homage).mp3",
|
||||
"09 Wheel (Featuring John Hollenbeck & Theo Bleckmann).mp3",
|
||||
"10 Scared Song (Featuring Pamela Z).mp3",
|
||||
"11 Boat Song (Featuring Rubin Kodheli).mp3",
|
||||
"12 Gathering (Featuring Lee Ranaldo Remix).mp3",
|
||||
"13 Evening (Featuring Henry Grimes Remix).mp3"
|
||||
{
|
||||
"title": "_60_01 Greensleeves",
|
||||
"media": "_60_01 Greensleeves.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_60_02 Nota",
|
||||
"media": "_60_02 Nota.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_60_03 Duet For Voice And Echoplex",
|
||||
"media": "_60_03 Duet For Voice And Echoplex.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_60_04 Candy Bullets And Moon",
|
||||
"media": "_60_04 Candy Bullets And Moon.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_60_05 Trance",
|
||||
"media": "_60_05 Trance.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_60_06 Epic I",
|
||||
"media": "_60_06 Epic I.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_60_07 Paris",
|
||||
"media": "_60_07 Paris.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_60_08 Biography",
|
||||
"media": "_60_08 Biography.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_60_09 Mill",
|
||||
"media": "_60_09 Mill.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_60_10 The Tale",
|
||||
"media": "_60_10 The Tale.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_60_11 Quarry Weave",
|
||||
"media": "_60_11 Quarry Weave.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_60_12 Epic II",
|
||||
"media": "_60_12 Epic II.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_60_13 Tower",
|
||||
"media": "_60_13 Tower.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_60_14 Mill",
|
||||
"media": "_60_14 Mill.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_60_15 Do You Be_",
|
||||
"media": "_60_15 Do You Be_.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_60_16 Quarry Procession",
|
||||
"media": "_60_16 Quarry Procession.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_60_17 Porch",
|
||||
"media": "_60_17 Porch.mp3"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "",
|
||||
"title": "Biography (from Education of the Girlchild)",
|
||||
"details": "Big Ego Records, 1978",
|
||||
"parent_dir": "music_sound_various",
|
||||
"media": "MONK MIX Remixes and Interpretations of Music by Meredith Monk CD2",
|
||||
"media": "Biography (from Education of the Girlchild)_Big Ego Records, 1978",
|
||||
"image": "Biography (from Education of the Girlchild)_Big Ego Records, 1978.jpg",
|
||||
"album": true,
|
||||
"tracks": [
|
||||
"01 Dawn (feat. Dj Spooky Remix).mp3",
|
||||
"02 Rain (feat. Vijay Iyer Revelation Mix Featuring Latasha N. Nevada Diggs).mp3",
|
||||
"03 Atlas Ascending (feat. Todd Reynolds Remix).mp3",
|
||||
"04 Epic (feat. Dj Rekha & Raj Star Remix).mp3",
|
||||
"05 Memory Song (feat. Miho Hatori Remix).mp3",
|
||||
"06 Travellers (feat. King Britt Idm Mix).mp3",
|
||||
"07 Night Vs. Lullaby (feat. Matt Marks Remix).mp3",
|
||||
"08 Double Fiesta (feat. Arto Lindsay Remix).mp3",
|
||||
"09 Long Shadows (feat. Scanner Entwine Mix).mp3",
|
||||
"10 Dolmen Music, Part 1 (feat. Shodekeh's Embody & Continuums Remix).mp3",
|
||||
"11 Braid (feat. High Priest _ Hprizm Ghostlover Remix).mp3",
|
||||
"12 Vocal_ Mill Feuille (feat. Sussan Deyhim Remix).mp3"
|
||||
{
|
||||
"title": "_63_13 Biography_Big Ego album",
|
||||
"media": "_63_13 Biography_Big Ego album.m4a"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "",
|
||||
"title": "KEY: an albm of invisible theater",
|
||||
"details": "Lovely Music, 1971",
|
||||
"parent_dir": "music_sound_various",
|
||||
"media": "_55 Songs from the Hill-Tablet",
|
||||
"media": "KEY: an albm of invisible theater_Lovely Music, 1971",
|
||||
"image": "KEY: an albm of invisible theater_Lovely Music, 1971.jpg",
|
||||
"album": true,
|
||||
"tracks": [
|
||||
"_55_01 Lullaby.mp3",
|
||||
"_55_02 Mesa.mp3",
|
||||
"_55_03 Jade (old woman's song).mp3",
|
||||
"_55_04 Wa-lie-oh.mp3",
|
||||
"_55_05 Insect.mp3",
|
||||
"_55_06 Descending.mp3",
|
||||
"_55_07 Silo.mp3",
|
||||
"_55_08 Bird Code.mp3",
|
||||
"_55_09 Jew's Harp.mp3",
|
||||
"_55_10 Prairie Ghost.mp3",
|
||||
"_55_11 Tablet.mp3"
|
||||
{
|
||||
"title": "_57_01 Porch",
|
||||
"media": "_57_01 Porch.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_57_02 Understreet",
|
||||
"media": "_57_02 Understreet.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_57_03 What Does It Mean_",
|
||||
"media": "_57_03 What Does It Mean_.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_57_04 Vision #1",
|
||||
"media": "_57_04 Vision #1.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_57_05 Fat Stream",
|
||||
"media": "_57_05 Fat Stream.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_57_06 Vision #2",
|
||||
"media": "_57_06 Vision #2.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_57_07 Do You Be_",
|
||||
"media": "_57_07 Do You Be_.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_57_08 Vision (#3)",
|
||||
"media": "_57_08 Vision (#3).mp3"
|
||||
},
|
||||
{
|
||||
"title": "_57_09 Change",
|
||||
"media": "_57_09 Change.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_57_10 Dungeon",
|
||||
"media": "_57_10 Dungeon.mp3"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "",
|
||||
"title": "MEMORY GAME",
|
||||
"details": "Cantaloupe Music, 2020",
|
||||
"parent_dir": "music_sound_various",
|
||||
"media": "_56 Our Lady of Late",
|
||||
"media": "MEMORY GAME_Cantaloupe Music, 2020",
|
||||
"image": "MEMORY GAME_Cantaloupe Music, 2020.jpg",
|
||||
"album": true,
|
||||
"tracks": [
|
||||
"_56_01 Prologue.mp3",
|
||||
"_56_02 Unison.mp3",
|
||||
"_56_03 Knee.mp3",
|
||||
"_56_04 Hey Rhythm.mp3",
|
||||
"_56_05 Cow Song.mp3",
|
||||
"_56_06 Sigh.mp3",
|
||||
"_56_07 Morning.mp3",
|
||||
"_56_08 Slide.mp3",
|
||||
"_56_09 Waltz.mp3",
|
||||
"_56_10 Prophecy.mp3",
|
||||
"_56_11 Dumb.mp3",
|
||||
"_56_12 Conversation.mp3",
|
||||
"_56_13 Low Ring.mp3",
|
||||
"_56_14 High Ring.mp3",
|
||||
"_56_15 Free.mp3",
|
||||
"_56_16 Edge.mp3",
|
||||
"_56_17 Scale Down.mp3",
|
||||
"_56_18 Epilogue.mp3"
|
||||
{
|
||||
"title": "_58_01 Spaceship",
|
||||
"media": "_58_01 Spaceship.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_58_02 Gamemaster's Song",
|
||||
"media": "_58_02 Gamemaster's Song.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_58_03 Migration",
|
||||
"media": "_58_03 Migration.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_58_04 Memory Song",
|
||||
"media": "_58_04 Memory Song.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_58_05 Downfall",
|
||||
"media": "_58_05 Downfall.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_58_06 Waltz In 5s",
|
||||
"media": "_58_06 Waltz In 5s.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_58_07 Tokyo CHa Cha",
|
||||
"media": "_58_07 Tokyo CHa Cha.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_58_08 Totentanz",
|
||||
"media": "_58_08 Totentanz.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_58_09 Double Fiesta",
|
||||
"media": "_58_09 Double Fiesta.mp3"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "",
|
||||
"title": "MONK MIX Remixes and Interpretations of Music by Meredith Monk (CD1)",
|
||||
"details": "The House Foundation for the Arts, 2012",
|
||||
"parent_dir": "music_sound_various",
|
||||
"media": "_57 KEY-an album of invisible theater",
|
||||
"media": "MONK MIX Remixes and Interpretations of Music by Meredith Monk (CD1)_The House Foundation for the Arts, 2012",
|
||||
"image": "MONK MIX Remixes and Interpretations of Music by Meredith Monk (CD1)_The House Foundation for the Arts, 2012.jpg",
|
||||
"album": true,
|
||||
"tracks": [
|
||||
"_57_01 Porch.mp3",
|
||||
"_57_02 Understreet.mp3",
|
||||
"_57_03 What Does It Mean_.mp3",
|
||||
"_57_04 Vision #1.mp3",
|
||||
"_57_05 Fat Stream.mp3",
|
||||
"_57_06 Vision #2.mp3",
|
||||
"_57_07 Do You Be_.mp3",
|
||||
"_57_08 Vision (#3).mp3",
|
||||
"_57_09 Change.mp3",
|
||||
"_57_10 Dungeon.mp3"
|
||||
{
|
||||
"title": "01 Gotham Lullaby (Featuring Björk With The Brodsky Quartet)",
|
||||
"media": "01 Gotham Lullaby (Featuring Björk With The Brodsky Quartet).mp3"
|
||||
},
|
||||
{
|
||||
"title": "02 Caldera Chimera (Featuring Gabriel Prokofiev Remix)",
|
||||
"media": "02 Caldera Chimera (Featuring Gabriel Prokofiev Remix).mp3"
|
||||
},
|
||||
{
|
||||
"title": "03 Click Song #1 (Featuring Don Byron)",
|
||||
"media": "03 Click Song #1 (Featuring Don Byron).mp3"
|
||||
},
|
||||
{
|
||||
"title": "04 Double Fiesta (Featuring Meredith Monk & Bang On A Can)",
|
||||
"media": "04 Double Fiesta (Featuring Meredith Monk & Bang On A Can).mp3"
|
||||
},
|
||||
{
|
||||
"title": "05 Astronaut Anthem (Featuring Sakamoto Remix)",
|
||||
"media": "05 Astronaut Anthem (Featuring Sakamoto Remix).mp3"
|
||||
},
|
||||
{
|
||||
"title": "06 Shaking (Featuring Lukas Ligeti) [Pyrolator Remix]",
|
||||
"media": "06 Shaking (Featuring Lukas Ligeti) [Pyrolator Remix].mp3"
|
||||
},
|
||||
{
|
||||
"title": "07 Last Song (Featuring Caetano Veloso)",
|
||||
"media": "07 Last Song (Featuring Caetano Veloso).mp3"
|
||||
},
|
||||
{
|
||||
"title": "08 Fat Stream (Featuring Nico_s Piano Homage)",
|
||||
"media": "08 Fat Stream (Featuring Nico_s Piano Homage).mp3"
|
||||
},
|
||||
{
|
||||
"title": "09 Wheel (Featuring John Hollenbeck & Theo Bleckmann)",
|
||||
"media": "09 Wheel (Featuring John Hollenbeck & Theo Bleckmann).mp3"
|
||||
},
|
||||
{
|
||||
"title": "10 Scared Song (Featuring Pamela Z)",
|
||||
"media": "10 Scared Song (Featuring Pamela Z).mp3"
|
||||
},
|
||||
{
|
||||
"title": "11 Boat Song (Featuring Rubin Kodheli)",
|
||||
"media": "11 Boat Song (Featuring Rubin Kodheli).mp3"
|
||||
},
|
||||
{
|
||||
"title": "12 Gathering (Featuring Lee Ranaldo Remix)",
|
||||
"media": "12 Gathering (Featuring Lee Ranaldo Remix).mp3"
|
||||
},
|
||||
{
|
||||
"title": "13 Evening (Featuring Henry Grimes Remix)",
|
||||
"media": "13 Evening (Featuring Henry Grimes Remix).mp3"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "",
|
||||
"title": "MONK MIX Remixes and Interpretations of Music by Meredith Monk (CD2)",
|
||||
"details": "The House Foundation for the Arts, 2012",
|
||||
"parent_dir": "music_sound_various",
|
||||
"media": "_58 MEMORY GAME",
|
||||
"media": "MONK MIX Remixes and Interpretations of Music by Meredith Monk (CD2)_The House Foundation for the Arts, 2012",
|
||||
"image": "MONK MIX Remixes and Interpretations of Music by Meredith Monk (CD2)_The House Foundation for the Arts, 2012.jpg",
|
||||
"album": true,
|
||||
"tracks": [
|
||||
"_58_01 Spaceship.mp3",
|
||||
"_58_02 Gamemaster's Song.mp3",
|
||||
"_58_03 Migration.mp3",
|
||||
"_58_04 Memory Song.mp3",
|
||||
"_58_05 Downfall.mp3",
|
||||
"_58_06 Waltz In 5s.mp3",
|
||||
"_58_07 Tokyo CHa Cha.mp3",
|
||||
"_58_08 Totentanz.mp3",
|
||||
"_58_09 Double Fiesta.mp3"
|
||||
{
|
||||
"title": "01 Dawn (feat. Dj Spooky Remix)",
|
||||
"media": "01 Dawn (feat. Dj Spooky Remix).mp3"
|
||||
},
|
||||
{
|
||||
"title": "02 Rain (feat. Vijay Iyer Revelation Mix Featuring Latasha N. Nevada Diggs)",
|
||||
"media": "02 Rain (feat. Vijay Iyer Revelation Mix Featuring Latasha N. Nevada Diggs).mp3"
|
||||
},
|
||||
{
|
||||
"title": "03 Atlas Ascending (feat. Todd Reynolds Remix)",
|
||||
"media": "03 Atlas Ascending (feat. Todd Reynolds Remix).mp3"
|
||||
},
|
||||
{
|
||||
"title": "04 Epic (feat. Dj Rekha & Raj Star Remix)",
|
||||
"media": "04 Epic (feat. Dj Rekha & Raj Star Remix).mp3"
|
||||
},
|
||||
{
|
||||
"title": "05 Memory Song (feat. Miho Hatori Remix)",
|
||||
"media": "05 Memory Song (feat. Miho Hatori Remix).mp3"
|
||||
},
|
||||
{
|
||||
"title": "06 Travellers (feat. King Britt Idm Mix)",
|
||||
"media": "06 Travellers (feat. King Britt Idm Mix).mp3"
|
||||
},
|
||||
{
|
||||
"title": "07 Night Vs. Lullaby (feat. Matt Marks Remix)",
|
||||
"media": "07 Night Vs. Lullaby (feat. Matt Marks Remix).mp3"
|
||||
},
|
||||
{
|
||||
"title": "08 Double Fiesta (feat. Arto Lindsay Remix)",
|
||||
"media": "08 Double Fiesta (feat. Arto Lindsay Remix).mp3"
|
||||
},
|
||||
{
|
||||
"title": "09 Long Shadows (feat. Scanner Entwine Mix)",
|
||||
"media": "09 Long Shadows (feat. Scanner Entwine Mix).mp3"
|
||||
},
|
||||
{
|
||||
"title": "10 Dolmen Music, Part 1 (feat. Shodekeh's Embody & Continuums Remix)",
|
||||
"media": "10 Dolmen Music, Part 1 (feat. Shodekeh's Embody & Continuums Remix).mp3"
|
||||
},
|
||||
{
|
||||
"title": "11 Braid (feat. High Priest _ Hprizm Ghostlover Remix)",
|
||||
"media": "11 Braid (feat. High Priest _ Hprizm Ghostlover Remix).mp3"
|
||||
},
|
||||
{
|
||||
"title": "12 Vocal_ Mill Feuille (feat. Sussan Deyhim Remix)",
|
||||
"media": "12 Vocal_ Mill Feuille (feat. Sussan Deyhim Remix).mp3"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "",
|
||||
"title": "Monk and the Abbess",
|
||||
"details": "BMG, 1996",
|
||||
"parent_dir": "music_sound_various",
|
||||
"media": "_60 Beginnings",
|
||||
"media": "Monk and the Abbess_BMG, 1996",
|
||||
"image": "Monk and the Abbess_BMG, 1996.jpg",
|
||||
"album": true,
|
||||
"tracks": [
|
||||
"_60_01 Greensleeves.mp3",
|
||||
"_60_02 Nota.mp3",
|
||||
"_60_03 Duet For Voice And Echoplex.mp3",
|
||||
"_60_04 Candy Bullets And Moon.mp3",
|
||||
"_60_05 Trance.mp3",
|
||||
"_60_06 Epic I.mp3",
|
||||
"_60_07 Paris.mp3",
|
||||
"_60_08 Biography.mp3",
|
||||
"_60_09 Mill.mp3",
|
||||
"_60_10 The Tale.mp3",
|
||||
"_60_11 Quarry Weave.mp3",
|
||||
"_60_12 Epic II.mp3",
|
||||
"_60_13 Tower.mp3",
|
||||
"_60_14 Mill.mp3",
|
||||
"_60_15 Do You Be_.mp3",
|
||||
"_60_16 Quarry Procession.mp3",
|
||||
"_60_17 Porch.mp3"
|
||||
{
|
||||
"title": "_62_05 Dawn (1985)",
|
||||
"media": "_62_05 Dawn (1985).mp3"
|
||||
},
|
||||
{
|
||||
"title": "_62_06 Quarry weave 1 (1976)",
|
||||
"media": "_62_06 Quarry weave 1 (1976).mp3"
|
||||
},
|
||||
{
|
||||
"title": "_62_07 Quarry lullaby (1976)",
|
||||
"media": "_62_07 Quarry lullaby (1976).mp3"
|
||||
},
|
||||
{
|
||||
"title": "_62_08 Quarry weave 2 (1976)",
|
||||
"media": "_62_08 Quarry weave 2 (1976).mp3"
|
||||
},
|
||||
{
|
||||
"title": "_62_09 Farmer's song (1974)",
|
||||
"media": "_62_09 Farmer's song (1974).mp3"
|
||||
},
|
||||
{
|
||||
"title": "_62_10 Astronaut anthem (1983)",
|
||||
"media": "_62_10 Astronaut anthem (1983).mp3"
|
||||
},
|
||||
{
|
||||
"title": "_62_11 Nightfall (1995)",
|
||||
"media": "_62_11 Nightfall (1995).mp3"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "",
|
||||
"title": "Our Lady of Late",
|
||||
"details": "Minona Records, 1974 and Wergo, 1986",
|
||||
"parent_dir": "music_sound_various",
|
||||
"media": "_61 Radio Songs",
|
||||
"media": "Our Lady of Late_Minona Records, 1974 and Wergo, 1986",
|
||||
"image": "Our Lady of Late_Minona Records, 1974 and Wergo, 1986.jpg",
|
||||
"album": true,
|
||||
"tracks": [
|
||||
"_61_01 Quarry Radio.mp3",
|
||||
"_61_02 Gotham Blues.mp3",
|
||||
"_61_03 Quarry Waltz.mp3",
|
||||
"_61_04 Gotham Lullaby.mp3"
|
||||
{
|
||||
"title": "_56_01 Prologue",
|
||||
"media": "_56_01 Prologue.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_56_02 Unison",
|
||||
"media": "_56_02 Unison.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_56_03 Knee",
|
||||
"media": "_56_03 Knee.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_56_04 Hey Rhythm",
|
||||
"media": "_56_04 Hey Rhythm.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_56_05 Cow Song",
|
||||
"media": "_56_05 Cow Song.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_56_06 Sigh",
|
||||
"media": "_56_06 Sigh.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_56_07 Morning",
|
||||
"media": "_56_07 Morning.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_56_08 Slide",
|
||||
"media": "_56_08 Slide.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_56_09 Waltz",
|
||||
"media": "_56_09 Waltz.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_56_10 Prophecy",
|
||||
"media": "_56_10 Prophecy.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_56_11 Dumb",
|
||||
"media": "_56_11 Dumb.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_56_12 Conversation",
|
||||
"media": "_56_12 Conversation.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_56_13 Low Ring",
|
||||
"media": "_56_13 Low Ring.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_56_14 High Ring",
|
||||
"media": "_56_14 High Ring.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_56_15 Free",
|
||||
"media": "_56_15 Free.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_56_16 Edge",
|
||||
"media": "_56_16 Edge.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_56_17 Scale Down",
|
||||
"media": "_56_17 Scale Down.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_56_18 Epilogue",
|
||||
"media": "_56_18 Epilogue.mp3"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "",
|
||||
"title": "Radio Songs",
|
||||
"details": "The sound of White Columns, 2014",
|
||||
"parent_dir": "music_sound_various",
|
||||
"media": "_62 Monk and the Abbiss",
|
||||
"media": "Radio Songs_The sound of White Columns, 2014",
|
||||
"image": "Radio Songs_The sound of White Columns, 2014.jpg",
|
||||
"album": true,
|
||||
"tracks": [
|
||||
"_62_05 Dawn (1985).mp3",
|
||||
"_62_06 Quarry weave 1 (1976).mp3",
|
||||
"_62_07 Quarry lullaby (1976).mp3",
|
||||
"_62_08 Quarry weave 2 (1976).mp3",
|
||||
"_62_09 Farmer's song (1974).mp3",
|
||||
"_62_10 Astronaut anthem (1983).mp3",
|
||||
"_62_11 Nightfall (1995).mp3"
|
||||
{
|
||||
"title": "_61_01 Quarry Radio",
|
||||
"media": "_61_01 Quarry Radio.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_61_02 Gotham Blues",
|
||||
"media": "_61_02 Gotham Blues.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_61_03 Quarry Waltz",
|
||||
"media": "_61_03 Quarry Waltz.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_61_04 Gotham Lullaby",
|
||||
"media": "_61_04 Gotham Lullaby.mp3"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "",
|
||||
"title": "Songs from the Hill-Tablet",
|
||||
"details": "Wergo, 1979",
|
||||
"parent_dir": "music_sound_various",
|
||||
"media": "_63 Biography (from Education of the Girlchild)",
|
||||
"media": "Songs from the Hill-Tablet_Wergo, 1979",
|
||||
"image": "Songs from the Hill-Tablet_Wergo, 1979.jpg",
|
||||
"album": true,
|
||||
"tracks": [
|
||||
"_63_13 Biography_Big Ego album.m4a"
|
||||
{
|
||||
"title": "_55_01 Lullaby",
|
||||
"media": "_55_01 Lullaby.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_55_02 Mesa",
|
||||
"media": "_55_02 Mesa.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_55_03 Jade (old woman's song)",
|
||||
"media": "_55_03 Jade (old woman's song).mp3"
|
||||
},
|
||||
{
|
||||
"title": "_55_04 Wa-lie-oh",
|
||||
"media": "_55_04 Wa-lie-oh.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_55_05 Insect",
|
||||
"media": "_55_05 Insect.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_55_06 Descending",
|
||||
"media": "_55_06 Descending.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_55_07 Silo",
|
||||
"media": "_55_07 Silo.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_55_08 Bird Code",
|
||||
"media": "_55_08 Bird Code.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_55_09 Jew's Harp",
|
||||
"media": "_55_09 Jew's Harp.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_55_10 Prairie Ghost",
|
||||
"media": "_55_10 Prairie Ghost.mp3"
|
||||
},
|
||||
{
|
||||
"title": "_55_11 Tablet",
|
||||
"media": "_55_11 Tablet.mp3"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -1 +0,0 @@
|
|||
[]
|
|
@ -1,63 +1,65 @@
|
|||
[
|
||||
{
|
||||
"title": "Specimen Days",
|
||||
"details": "The Public Theater, New York, 1981. 1:26:17",
|
||||
"media": "-34 Specimen Days.m4v",
|
||||
"title": "Cellular Songs",
|
||||
"details": "UCLA, Los Angeles, California, 2019",
|
||||
"parent_dir": "theatre",
|
||||
"media": "Cellular Songs_UCLA, Los Angeles, California, 2019.mp4",
|
||||
"image": "Cellular Songs_UCLA, Los Angeles, California, 2019.jpg"
|
||||
},
|
||||
{
|
||||
"title": "The Games: a science fiction opera",
|
||||
"details": "Brooklyn Academy of Music (BAM), New York, 1984. 2:00:35",
|
||||
"media": "-37 MMonk_TheGames_BAM1984.m4v",
|
||||
"title": "Education of the Girlchild",
|
||||
"details": "solo, Common Ground, NYC, 1973",
|
||||
"parent_dir": "theatre",
|
||||
"media": "Education of the Girlchild_solo, Common Ground, NYC, 1973..m4v",
|
||||
"image": "Education of the Girlchild_solo, Common Ground, NYC, 1973..jpg"
|
||||
},
|
||||
{
|
||||
"title": "Facing North",
|
||||
"details": "George Washington University, Washington, DC, 1992. 54:32",
|
||||
},
|
||||
{
|
||||
"title": "The Politics of Quiet",
|
||||
"details": "Brooklyn Academy of Music, BAM, New York, 1996. 1:43:46",
|
||||
"media": "-36 The Politics of Quiet at BAM - 10.13.96.m4v",
|
||||
"details": "George Washington University, Washington, DC, 1992",
|
||||
"parent_dir": "theatre",
|
||||
"media": "Facing North_George Washington University, Washington, DC, 1992.mp4",
|
||||
"image": "Facing North_George Washington University, Washington, DC, 1992.jpg"
|
||||
},
|
||||
{
|
||||
"title": "Magic Frequencies (excerpts)",
|
||||
"details": "Muffathalle, Munich, Germany, 1998. 25:49",
|
||||
"media": "-42 1998 Magic Frequencies (excerpts) BetaCamSP transfer 2021.m4v"
|
||||
"details": "Muffathalle, Munich, Germany, 1998",
|
||||
"parent_dir": "theatre",
|
||||
"media": "Magic Frequencies (excerpts)_Muffathalle, Munich, Germany, 1998.m4v",
|
||||
"image": "Magic Frequencies (excerpts)_Muffathalle, Munich, Germany, 1998.jpg"
|
||||
},
|
||||
{
|
||||
"title":"A Celebration Service",
|
||||
"details": "St. Mark’s Church, NYC, 1999. 55:02",
|
||||
"media": "-35 Meredith Monk - A Celebration Service_ Danspace at St. Mark's Church_1999.m4v",
|
||||
"title": "Meredith Monk",
|
||||
"details": "A Celebration Service",
|
||||
"parent_dir": "theatre",
|
||||
"media": "Meredith Monk_A Celebration Service_ Danspace at St. Mark's Church_1999.m4v",
|
||||
"image": "Meredith Monk_A Celebration Service_ Danspace at St. Mark's Church_1999.jpg"
|
||||
},
|
||||
{
|
||||
impermanence, Brooklyn Academy of Music (BAM), New York, 2006. 1:22:03
|
||||
"title": "Songs of Ascension",
|
||||
"details": "Brooklyn Academy of Music (BAM), New York, 2009",
|
||||
"parent_dir": "theatre",
|
||||
"media": "Songs of Ascension_Brooklyn Academy of Music (BAM), New York, 2009.mp4",
|
||||
"image": "Songs of Ascension_Brooklyn Academy of Music (BAM), New York, 2009.jpg"
|
||||
},
|
||||
{
|
||||
Songs of Ascension, Brooklyn Academy of Music (BAM), New York, 2009. 1:17:29
|
||||
"title": "Specimen Days",
|
||||
"details": "The Public Theater, New York, 1981",
|
||||
"parent_dir": "theatre",
|
||||
"media": "Specimen Days_The Public Theater, New York, 1981.m4v",
|
||||
"image": "Specimen Days_The Public Theater, New York, 1981.jpg"
|
||||
},
|
||||
{
|
||||
"title": "On Behalf of Nature",
|
||||
"details": "UCLA, Los Angeles, California, 2013. 1:14:55"
|
||||
"media": ""
|
||||
"title": "The Games",
|
||||
"details": "a science fiction opera, Brooklyn Academy of Music (BAM), New York, 1984",
|
||||
"parent_dir": "theatre",
|
||||
"media": "The Games_a science fiction opera, Brooklyn Academy of Music (BAM), New York, 1984.m4v",
|
||||
"image": "The Games_a science fiction opera, Brooklyn Academy of Music (BAM), New York, 1984.jpg"
|
||||
},
|
||||
{
|
||||
"title": "impermanence",
|
||||
"details": "Brooklyn Academy of Music (BAM), New York, 2006",
|
||||
"parent_dir": "theatre",
|
||||
"media": "impermanence_Brooklyn Academy of Music (BAM), New York, 2006.mp4",
|
||||
"image": "impermanence_Brooklyn Academy of Music (BAM), New York, 2006.jpg"
|
||||
}
|
||||
|
||||
{
|
||||
Cellular Songs, UCLA, Los Angeles, California, 2019. 1:24:07
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
"media": "-29 Education of the Gildchild solo_Common Ground_1973.m4v",
|
||||
"media": "-30 Quarry_full film_1977_FINAL_20200127_added to dropbox.m4v",
|
||||
"media": "-33 MEREDITH_MONK_SOLO_CONCERT_1980.m4v",
|
||||
"media": "-38 MeredithMonk_SoloConcert_College des Bernadins Paris_20120516.m4v",
|
||||
"media": "-39 Meredith Monk with Katie Geissinger in Concert, Haus der Kunst, Munich, Germany (2012).m4v",
|
||||
"media": "-40 Candy_Bullets_and_Moon.m4v",
|
||||
"media": "-41 Monk_Anthem_Final.m4v",
|
||||
]
|
||||
|
|
|
@ -1,6 +1,29 @@
|
|||
import fs from 'fs/promises'
|
||||
import path from 'path'
|
||||
import { exec } from 'child_process'
|
||||
|
||||
// WAVEFORM GENERATION
|
||||
// TODO@mx use node-js library
|
||||
async function generateWaveform(audioFile, outputDir) {
|
||||
const inputFile = path.join(outputDir, audioFile)
|
||||
audioFile = audioFile.replace(/\.[^/.]+$/, '.png')
|
||||
const outputPath = path.join(outputDir || '.', audioFile)
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
exec(
|
||||
`audiowaveform -i '${inputFile}' -o '${outputPath}' --output-format png -z auto -w 640 -h 180 --background-color 00000000 --waveform-color FFFFFF50 --waveform-style bars --bar-style rounded --border-color 00000000 --bar-width 4 --bar-gap 6 --no-axis-labels`,
|
||||
(error, stdOut) => {
|
||||
if (error) {
|
||||
console.error(error)
|
||||
reject(error)
|
||||
} else {
|
||||
resolve(audioFile)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// MAIN FUNCTION
|
||||
async function main() {
|
||||
// variable for incoming variable
|
||||
let mediaDir = ''
|
||||
|
@ -8,90 +31,189 @@ async function main() {
|
|||
let recurse = false
|
||||
let imagesOnly = false
|
||||
let dryRun = false
|
||||
let formatted = null
|
||||
let waveform = false
|
||||
let update = []
|
||||
|
||||
// get command line arguments
|
||||
process.argv.forEach(function (val, index) {
|
||||
// console.log(index + ': ' + val)
|
||||
if (val == '-dir') {
|
||||
// console.log(process.argv[index + 1])
|
||||
mediaDir = process.argv[index + 1] || ''
|
||||
}
|
||||
switch (val) {
|
||||
case '-dir':
|
||||
mediaDir = process.argv[index + 1] || ''
|
||||
break
|
||||
case '-o':
|
||||
outputDir = process.argv[index + 1] || ''
|
||||
break
|
||||
case '-u':
|
||||
update = process.argv[index + 1].match(/(title|details|media|image[s]*|tracks|)/i)
|
||||
? process.argv[index + 1]
|
||||
.split(',')
|
||||
.filter(a => [
|
||||
'title',
|
||||
'details',
|
||||
'media',
|
||||
'image',
|
||||
'tracks',
|
||||
'images'
|
||||
].includes(a))
|
||||
: true
|
||||
break
|
||||
case '-r':
|
||||
recurse = true
|
||||
break
|
||||
case '--images-only':
|
||||
imagesOnly = true
|
||||
break
|
||||
case '--dry-run':
|
||||
dryRun = true
|
||||
break
|
||||
case '--formatted':
|
||||
formatted = ['parent', 'recurse', 'both' ].includes(process.argv[index + 1]) ? process.argv[index + 1] : 'both'
|
||||
break
|
||||
case '--gen-waveform':
|
||||
waveform = true
|
||||
break
|
||||
|
||||
if (val == '--dry-run') {
|
||||
dryRun = true
|
||||
}
|
||||
|
||||
if (val == '--images') {
|
||||
imagesOnly = true
|
||||
}
|
||||
|
||||
if (val == '-r' || val == '-R') {
|
||||
recurse = true
|
||||
}
|
||||
|
||||
if (val == '-o') {
|
||||
outputDir = process.argv[index + 1]
|
||||
default:
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
// if no media dir jump out
|
||||
// if no media dir passed jump out
|
||||
if (!mediaDir) {
|
||||
console.log('no directory passed to script')
|
||||
return 0
|
||||
}
|
||||
//
|
||||
// read directory
|
||||
const dirList = await fs.readdir(mediaDir)
|
||||
|
||||
// variable to hold media
|
||||
let media = []
|
||||
let images = []
|
||||
|
||||
// read directory
|
||||
const dirList = await fs.readdir(mediaDir)
|
||||
|
||||
if (!recurse) {
|
||||
// If recursing we are making the "media" the directories where we will find the
|
||||
// acutal media to playback or see
|
||||
if (recurse) {
|
||||
media = dirList.filter(i => !i.match(/\.[^/.]+$/))
|
||||
} else {
|
||||
media = dirList.filter(i => i.match(/.(mp\d|m\d\w)$/i))
|
||||
images = dirList.filter(i => i.match(/.(jp\w*g|png)$/i))
|
||||
}
|
||||
|
||||
// create an array of images found in the directory as well
|
||||
images = dirList.filter(i => i.match(/.(jp\w*g|png)$/i))
|
||||
|
||||
// clean up directory for json
|
||||
// clean up passed directory for json
|
||||
let parent_dir = mediaDir
|
||||
.match(/(?<=\/)(\w|\d)+\/*$/i)[0]
|
||||
.replace(/\/$/i, '')
|
||||
|
||||
// set an output directory if not set by flags
|
||||
if (!outputDir) {
|
||||
outputDir = '.'
|
||||
}
|
||||
|
||||
const obj = await Promise.all(media.map(async (m, i) => {
|
||||
// THE MAIN EVENT
|
||||
const obj = await Promise.all(media.map(async m => {
|
||||
|
||||
// setup structure
|
||||
const _r = {
|
||||
title: '',
|
||||
details: '',
|
||||
...genMetadata(m, formatted == 'parent' || formatted == 'both'),
|
||||
parent_dir,
|
||||
media: m,
|
||||
image: images[i],
|
||||
image: ''
|
||||
}
|
||||
|
||||
// if we are scanning for images only, remove the 'image' property
|
||||
// as it will be saved in the media property
|
||||
if (imagesOnly) {
|
||||
delete _r.image
|
||||
} else {
|
||||
if (waveform) {
|
||||
// if waveform generate waveform
|
||||
_r.image = await generateWaveform(m, mediaDir)
|
||||
} else {
|
||||
// if not compare the media name with the image name
|
||||
// and if a match assign it to 'image' variable from earlier
|
||||
_r.image = linkImage(m.replace(/\.[^/.]+$/, ''), images)
|
||||
}
|
||||
}
|
||||
|
||||
// if recurse (again) now we are looking for the media in the folders
|
||||
if (recurse) {
|
||||
// create full path from the passed dir, and the recuring dir
|
||||
const rDir = path.join(mediaDir, m)
|
||||
const files = await fs.readdir(rDir)
|
||||
// read the dir
|
||||
let files = await fs.readdir(rDir)
|
||||
// filterout any rogue folders
|
||||
// generate the metadata for each file
|
||||
files = files.filter(f => f.match(/\.[^/.]+$/))
|
||||
files = files.map(f => {
|
||||
const { title, details } = genMetadata(f, formatted == 'recurse' || formatted == 'both')
|
||||
return { title, details, media: f }
|
||||
})
|
||||
|
||||
_r.album = true
|
||||
_r.tracks = files
|
||||
// if images only
|
||||
if (imagesOnly) {
|
||||
// setup object per image in array
|
||||
_r.images = files
|
||||
} else {
|
||||
_r.album = true
|
||||
_r.tracks = files
|
||||
}
|
||||
}
|
||||
|
||||
// return the result to the 'obj' variable
|
||||
return _r
|
||||
}))
|
||||
|
||||
const json = JSON.stringify(obj, null, 2)
|
||||
let output = `${parent_dir}.json`
|
||||
|
||||
// turn the obj variable into JSON
|
||||
const json = JSON.stringify(obj, null, 2)
|
||||
// set the output filename
|
||||
let outputFile = `${parent_dir}.json`
|
||||
|
||||
// check if file already exists at location
|
||||
// const dataFile = await fs.readFile(path.join(outputDir, outputFile), 'utf8')
|
||||
// console.log(JSON.parse(dataFile) || 'no data file exists')
|
||||
// update only new fields
|
||||
|
||||
// if dryrun
|
||||
if (dryRun) {
|
||||
// just console it out
|
||||
console.log(json)
|
||||
} else {
|
||||
fs.writeFile(path.join(outputDir, output), json)
|
||||
// write it to a file
|
||||
fs.writeFile(path.join(outputDir, outputFile), json)
|
||||
}
|
||||
}
|
||||
|
||||
function genMetadata(dir, formatted) {
|
||||
let title, details
|
||||
|
||||
// if formatted flag set
|
||||
if (formatted) {
|
||||
// split the incoming name from the map on the '_'
|
||||
// and set the first element to title, and the second to details
|
||||
let [ t, d ] = dir.split('_')
|
||||
// assign to return object
|
||||
title = t
|
||||
details = d ? d.replace(/\.+(mp\d|m\dv)$/i, '') : ''
|
||||
} else {
|
||||
// else just set title to filename without extensions
|
||||
title = dir.replace(/\.[^/.]+$/, '')
|
||||
}
|
||||
|
||||
return { title, details }
|
||||
}
|
||||
|
||||
function linkImage(name, images) {
|
||||
return images.find(i => {
|
||||
return i.replace(/\.[^/.]+$/, '') == name
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
main()
|
||||
|
|
50
src/App.js
50
src/App.js
|
@ -1,5 +1,6 @@
|
|||
import { LitElement, css, html, unsafeCSS } from 'lit'
|
||||
import Router from './api/Router.js'
|
||||
import { Task } from '@lit-labs/task'
|
||||
|
||||
import MainCSS from './assets/styles/main.scss?inline'
|
||||
|
||||
|
@ -10,13 +11,17 @@ import './components/Footer.js'
|
|||
import './assets/styles/main.scss'
|
||||
|
||||
export class App extends LitElement {
|
||||
static properties = {}
|
||||
static properties = {
|
||||
dialogEl: { state: true }
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
this.dialogEl = this.shadowRoot.querySelector('dialog')
|
||||
|
||||
Router.addEventListener('route-changed', () => {
|
||||
if ('startViewTransition' in document) {
|
||||
return document.startViewTransition(() => {
|
||||
|
@ -28,6 +33,27 @@ export class App extends LitElement {
|
|||
}
|
||||
})
|
||||
|
||||
this.addEventListener('single-fullscreen-image', ({ detail }) => {
|
||||
const { src, details } = detail
|
||||
const img = new Image()
|
||||
img.src = src
|
||||
this.dialogEl.appendChild(img)
|
||||
|
||||
if (detail.details) {
|
||||
const div = document.createElement('div')
|
||||
const p = document.createElement('p')
|
||||
p.textContent = details
|
||||
div.appendChild(p)
|
||||
this.dialogEl.appendChild(div)
|
||||
}
|
||||
|
||||
this.dialogEl.showModal()
|
||||
|
||||
this.dialogEl.addEventListener('click', () => {
|
||||
this.dialogEl.close()
|
||||
this.dialogEl.innerHTML = ''
|
||||
}, { once: true })
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -35,6 +61,8 @@ export class App extends LitElement {
|
|||
${Router.route.path == '/' ? '' : html`<mm-header title=${Router.route.title}></mm-header>`}
|
||||
${Router.render()}
|
||||
${Router.route.path == '/' ? '' : html`<mm-footer path=${Router.route.path}></mm-footer>`}
|
||||
<dialog class="popup">
|
||||
</dialog>
|
||||
`
|
||||
}
|
||||
|
||||
|
@ -45,6 +73,26 @@ export class App extends LitElement {
|
|||
flex-direction: column;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
dialog {
|
||||
margin: auto;
|
||||
border: none;
|
||||
|
||||
& div {
|
||||
padding-block-start: 1em;
|
||||
font-size: 1.25em;
|
||||
}
|
||||
|
||||
& img {
|
||||
display: block;
|
||||
max-height: calc(100vmin - 2em);
|
||||
max-width: calc(100vmin - 2em);
|
||||
}
|
||||
}
|
||||
|
||||
dialog::backdrop {
|
||||
background-color: #00000090;
|
||||
}
|
||||
` ]
|
||||
}
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ export default new Router({
|
|||
short: 'Unpublished',
|
||||
icon: 'headphones',
|
||||
group: 'Music & Sound',
|
||||
disabled: true,
|
||||
plugins: [
|
||||
lazy(() => import('../views/audio.js'))
|
||||
],
|
||||
|
@ -81,23 +82,23 @@ export default new Router({
|
|||
},
|
||||
{
|
||||
path: resolveRouterPath('theatre'),
|
||||
title: 'Music - Theatre Works',
|
||||
short: 'Theatre Works',
|
||||
icon: 'headphones',
|
||||
title: 'Music-Theatre Works',
|
||||
short: 'Music-Theatre',
|
||||
icon: 'film',
|
||||
plugins: [
|
||||
lazy(() => import('../views/audio.js'))
|
||||
lazy(() => import('../views/videos.js'))
|
||||
],
|
||||
render: () => html`<mm-audio></mm-audio>`
|
||||
render: () => html`<mm-videos></mm-videos>`
|
||||
},
|
||||
{
|
||||
path: resolveRouterPath('concerts'),
|
||||
title: 'Concert Recordings',
|
||||
short: 'Concerts',
|
||||
icon: 'headphones',
|
||||
icon: 'film',
|
||||
plugins: [
|
||||
lazy(() => import('../views/audio.js'))
|
||||
lazy(() => import('../views/videos.js'))
|
||||
],
|
||||
render: () => html`<mm-audio></mm-audio>`
|
||||
render: () => html`<mm-videos></mm-videos>`
|
||||
},
|
||||
{
|
||||
path: resolveRouterPath('films'),
|
||||
|
@ -114,6 +115,7 @@ export default new Router({
|
|||
title: 'Scores, Posters, Ephemera',
|
||||
short: 'images',
|
||||
icon: 'camera',
|
||||
disabled: true,
|
||||
plugins: [
|
||||
lazy(() => import('../views/images.js'))
|
||||
],
|
||||
|
|
|
@ -6,7 +6,6 @@ body {
|
|||
line-height: 1;
|
||||
font-size: 16px;
|
||||
|
||||
|
||||
--neutral-900: hsl(0 0% 0%);
|
||||
--neutral-700: hsl(220 10% 44%);
|
||||
--neutral-400: hsl(220 10% 88%);
|
||||
|
@ -18,6 +17,7 @@ body {
|
|||
--green-400: hsl(147 100% 34%);
|
||||
--green-200: hsl(147 100% 50%);
|
||||
|
||||
--neutral-gradient-600: linear-gradient(to top,rgba(208,210,214,1) 0%, rgba(141,142,145,1) 100%);
|
||||
--neutral-gradient-400: linear-gradient(to bottom, hsl(228, 5%, 82%) 0%, var(--neutral-400) 100%);
|
||||
--green-gradient-400: linear-gradient(to bottom, var(--green-400) 0%, var(--green-500) 100%);
|
||||
--green-inside-gradient-400: linear-gradient(to bottom, rgba(0, 154, 69, 1) 0%,rgba(177, 178, 181, 0) 100%), linear-gradient(rgba(0, 173, 78, 1),rgba(0, 173, 78, 1));
|
||||
|
|
|
@ -19,18 +19,26 @@ class AudioCard extends LitElement {
|
|||
}
|
||||
|
||||
clickHandler() {
|
||||
const event = new CustomEvent('select-audio', {
|
||||
bubbles: true, composed: true,
|
||||
detail: { ...this.details, idx: this.idx }
|
||||
})
|
||||
if (!this.selected) {
|
||||
const event = new CustomEvent('select-audio', {
|
||||
bubbles: true, composed: true,
|
||||
detail: { ...this.details, idx: this.idx }
|
||||
})
|
||||
|
||||
this.dispatchEvent(event)
|
||||
this.dispatchEvent(event)
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div class="card ${this.selected ? 'selected' : ''}" @click=${this.clickHandler}>
|
||||
<mm-icon name=${this.icon}></mm-icon>
|
||||
${this.details.album && this.details.image
|
||||
? html`<img
|
||||
class="albumCover"
|
||||
src=${this.details.image}
|
||||
/>`
|
||||
: html`<mm-icon name=${this.icon}></mm-icon>`
|
||||
}
|
||||
|
||||
<main>
|
||||
<p class="heading">${this.details?.title}</p>
|
||||
|
@ -54,10 +62,18 @@ class AudioCard extends LitElement {
|
|||
font-size: 3em;
|
||||
}
|
||||
|
||||
.albumCover {
|
||||
display: block;
|
||||
height: 3em;
|
||||
aspect-ratio: 1 / 1;
|
||||
object-fit: cover;
|
||||
background: lightgrey;
|
||||
}
|
||||
|
||||
.card {
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
grid-template-columns: min-content 1fr;
|
||||
grid-template-columns: auto 1fr;
|
||||
gap: 1em;
|
||||
align-items: center;
|
||||
padding-inline: 0.75em;
|
||||
|
@ -73,6 +89,10 @@ class AudioCard extends LitElement {
|
|||
.card.selected {
|
||||
outline: 2px solid var(--green-400, black);
|
||||
}
|
||||
|
||||
.info {
|
||||
max-width: 30ch;
|
||||
}
|
||||
` ]
|
||||
}
|
||||
|
||||
|
|
|
@ -43,13 +43,13 @@ class Footer extends LitElement {
|
|||
|
||||
renderLink(r, first = false) {
|
||||
return html`
|
||||
${first ? html`<span class="break"></span>` : '' }
|
||||
<a href=${r.path} class="${r.path == this.path ? 'selected' : ''}">
|
||||
${first && !r.disabled ? html`<span class="break"></span>` : '' }
|
||||
${!r.disabled ? html`<a href=${r.path} class="${r.path == this.path ? 'selected' : ''}">
|
||||
<mm-icon name=${r.icon}></mm-icon>
|
||||
<span>
|
||||
${r.short}
|
||||
</span>
|
||||
</a>
|
||||
</a>` : '' }
|
||||
`
|
||||
}
|
||||
|
||||
|
|
|
@ -18,9 +18,8 @@ class HorizontalScroller extends LitElement {
|
|||
static styles = css`
|
||||
:host {
|
||||
--col-width: 10em;
|
||||
--gap: 1em;
|
||||
--gap: 0.75em;
|
||||
display: flex;
|
||||
padding-block-end: 0.5em;
|
||||
}
|
||||
|
||||
.scroller {
|
||||
|
|
|
@ -39,6 +39,7 @@ class ImageCarousel extends LitElement {
|
|||
padding-inline-end: 0.5em;
|
||||
padding-block-start: 0.25em;
|
||||
padding-block-end: 0.75em;
|
||||
background: black;
|
||||
}
|
||||
|
||||
mm-image {
|
||||
|
|
|
@ -37,15 +37,19 @@ class ModularPlayer extends LitElement {
|
|||
this._initAudio()
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
console.log(this.details)
|
||||
}
|
||||
|
||||
_getTrack = new Task(
|
||||
this,
|
||||
async () => {
|
||||
try {
|
||||
if (this.details) {
|
||||
if (this.details?.tracks) {
|
||||
this.audio.src = `/media${this.details.media}/${this.details.tracks[this.track]}`
|
||||
this.audio.src = `${this.details.media}/${this.details.tracks[this.track].media}`
|
||||
} else {
|
||||
this.audio.src = `/media${this.details.media}.mp3`
|
||||
this.audio.src = `${this.details.media}`
|
||||
}
|
||||
this.audio.load()
|
||||
if (this.playing && this.audio.paused) {
|
||||
|
@ -95,7 +99,7 @@ class ModularPlayer extends LitElement {
|
|||
this.track = 0
|
||||
}
|
||||
|
||||
this.audio.src = `/media${this.details.media}/${this.details.tracks[this.track]}`
|
||||
this.audio.src = `${this.details.media}/${this.details.tracks[this.track].media}`
|
||||
this.audio.load()
|
||||
}
|
||||
})
|
||||
|
@ -170,20 +174,35 @@ class ModularPlayer extends LitElement {
|
|||
return `${percentage}%`
|
||||
}
|
||||
|
||||
showImage() {
|
||||
const event = new CustomEvent('single-fullscreen-image', {
|
||||
bubbles: true, composed: true,
|
||||
detail: { src: this.details.image }
|
||||
})
|
||||
|
||||
this.dispatchEvent(event)
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
return html`
|
||||
${ this.details ?
|
||||
html`<div class="player">
|
||||
${this.details.tracks ? html`
|
||||
<div class="tracklist">
|
||||
<h2>${this.details.title}</h2>
|
||||
<header>
|
||||
<img src=${this.details.image}
|
||||
@click=${this.showImage}
|
||||
/>
|
||||
<h2>${this.details.title}</h2>
|
||||
</header>
|
||||
|
||||
<div class="list">
|
||||
<ul>
|
||||
${this.details.tracks.map((t, i) => html`
|
||||
<li class="${this.track === i ? 'selected' : ''}" data-track-number=${i} @click=${this._selectTrack}>
|
||||
<mm-icon name="notes" class=${this.playing ? 'playing' : ''}></mm-icon>
|
||||
<span>${t}</span>
|
||||
<span>${t.title}</span>
|
||||
</li>`)}
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -191,7 +210,7 @@ ${ this.details ?
|
|||
` : html``}
|
||||
|
||||
<header>
|
||||
<h2>${this.details.tracks ? this.details?.tracks[this.track] : this.details.title}</h2>
|
||||
<h2>${this.details.tracks ? this.details?.tracks[this.track].title : this.details.title}</h2>
|
||||
${this.details.tracks ? '' : html`<p class="details">${this.details.details}</p>`}
|
||||
</header>
|
||||
|
||||
|
@ -216,7 +235,7 @@ ${ this.details ?
|
|||
@input=${this._seekTrack}
|
||||
class="progress"
|
||||
></mm-range>
|
||||
<img class="wav-img" loading="eager" src="/media${this.details.media}.png">
|
||||
<img class="wav-img" loading="eager" src="${this.details.image}">
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
@ -263,11 +282,11 @@ ${ this.details ?
|
|||
}
|
||||
|
||||
.player:has(.tracklist) {
|
||||
grid-template-rows: 60% 0.5fr 0.3fr 1fr;
|
||||
grid-template-rows: 67% 0.5fr 0.3fr 1fr;
|
||||
padding-block-end: 2em;
|
||||
gap: 0;
|
||||
|
||||
& header {
|
||||
& > header {
|
||||
margin-block-start: 1.5em;
|
||||
margin-block-end: 2em;
|
||||
}
|
||||
|
@ -300,23 +319,36 @@ ${ this.details ?
|
|||
|
||||
.tracklist {
|
||||
--tracklist-padding: calc(var(--padding) * 2);
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: var(--neutral-gradient-400);
|
||||
height: 100%;
|
||||
|
||||
> h2 {
|
||||
& header {
|
||||
margin-inline: var(--tracklist-padding);
|
||||
margin-block-start: 0.75em;
|
||||
margin-block-start: 1em;
|
||||
margin-block-end: 0.75em;
|
||||
padding-block-start: 0.75em;
|
||||
border-block-start: thin solid var(--green-400);
|
||||
display: flex;
|
||||
gap: 0.5em;
|
||||
align-items: end;
|
||||
color: black;
|
||||
|
||||
& img {
|
||||
height: 4em;
|
||||
aspect-ratio: 1 / 1;
|
||||
}
|
||||
|
||||
& > h2 {
|
||||
line-height: 1;
|
||||
max-width: 15ch;
|
||||
}
|
||||
}
|
||||
|
||||
> .list {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
top: calc(var(--tracklist-padding) * 2.5);
|
||||
right: var(--tracklist-padding);
|
||||
left: var(--tracklist-padding);
|
||||
& .list {
|
||||
flex-grow: 1;
|
||||
margin-inline: var(--tracklist-padding);
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
border-radius: 0.75em 0.75em 0 0;
|
||||
|
@ -391,6 +423,7 @@ ${ this.details ?
|
|||
}
|
||||
|
||||
.info:has(.waveform) {
|
||||
|
||||
& .time_pos,
|
||||
& .time_dur {
|
||||
position: absolute;
|
||||
|
|
|
@ -18,34 +18,42 @@ class NavCard extends LitElement {
|
|||
firstUpdated() {
|
||||
console.log(this.route)
|
||||
this.shadowRoot.host.addEventListener('click', () => {
|
||||
Router.navigate(this.route.path)
|
||||
if (!this.route.disabled) {
|
||||
Router.navigate(this.route.path)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
navigate(path) {
|
||||
path = path || this.route.path
|
||||
Router.navigate(path)
|
||||
if (!this.route.disabled) {
|
||||
path = path || this.route.path
|
||||
Router.navigate(path)
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div class="card">
|
||||
${Array.isArray(this.route) ? html`
|
||||
<p class="title">${this.route[0].group}</p>
|
||||
<header class="title">
|
||||
<span>${this.route[0].group}</span>
|
||||
</header>
|
||||
${this.route.map(r =>
|
||||
html`
|
||||
!r.disabled ? html`
|
||||
<button @click=${() => this.navigate(r.path)}>
|
||||
<mm-icon name=${r.icon}></mm-icon>
|
||||
${r.title}
|
||||
</button>
|
||||
`
|
||||
` : ''
|
||||
)}
|
||||
`
|
||||
:
|
||||
html`
|
||||
<p class="title">${this.route?.title}</p>
|
||||
<button class="iconOnly" @click=${() => this.navigate()}>
|
||||
<mm-icon name=${this.route.icon}></mm-icon>
|
||||
<header class="title">
|
||||
<span>${this.route?.title}</span>
|
||||
</header>
|
||||
<button class="iconOnly" @click=${this.navigate}>
|
||||
${!this.route.disabled ? html`<mm-icon name=${this.route.icon}></mm-icon>` : html`<span>coming soon...</span>`}
|
||||
</button>
|
||||
`
|
||||
}
|
||||
|
@ -88,6 +96,15 @@ class NavCard extends LitElement {
|
|||
font-size: 0.75em;
|
||||
text-align: center;
|
||||
border-bottom: thin solid var(--highlight-color);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 2.5em;
|
||||
|
||||
& > span {
|
||||
display: block;
|
||||
max-width: 18ch;
|
||||
margin-inline: auto;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
|
@ -105,6 +122,10 @@ class NavCard extends LitElement {
|
|||
text-shadow: 0 0 5px #ffffff;
|
||||
margin: 0;
|
||||
|
||||
&:has(span) {
|
||||
background: var(--neutral-gradient-600);
|
||||
}
|
||||
|
||||
&.iconOnly {
|
||||
display: flex;
|
||||
gap: 0;
|
||||
|
@ -112,6 +133,10 @@ class NavCard extends LitElement {
|
|||
justify-content: center;
|
||||
font-size: 1.5em;
|
||||
padding: 1em;
|
||||
|
||||
& > span {
|
||||
font-size: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
& mm-icon {
|
||||
|
|
|
@ -13,6 +13,7 @@ class VerticalCard extends LitElement {
|
|||
super()
|
||||
this.details = {}
|
||||
this.selected = false
|
||||
|
||||
}
|
||||
|
||||
select() {
|
||||
|
@ -30,7 +31,7 @@ class VerticalCard extends LitElement {
|
|||
return html`
|
||||
<div @click=${this.select} class=${this.selected ? 'selected' : ''}>
|
||||
<picture>
|
||||
<img src="/media/${Router.route.path}/thumbs/${this.details.media}">
|
||||
<img src="/media/${Router.route.path}/${this.details.image}">
|
||||
</picture>
|
||||
<aside>
|
||||
<p class="title">${this.details?.title}</p>
|
||||
|
@ -51,7 +52,7 @@ class VerticalCard extends LitElement {
|
|||
div {
|
||||
height: 100%;
|
||||
display: grid;
|
||||
grid-template-rows: 75% 25%;
|
||||
grid-template-rows: 72% 28%;
|
||||
background: lightgrey;
|
||||
line-height: 1;
|
||||
overflow: hidden;
|
||||
|
@ -59,10 +60,11 @@ class VerticalCard extends LitElement {
|
|||
background: var(--background-color);
|
||||
color: var(--font-color);
|
||||
align-content: start;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.selected {
|
||||
outline: 2px solid var(--color);
|
||||
outline: 1px solid var(--color);
|
||||
}
|
||||
|
||||
picture {
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import { LitElement, css, html } from 'lit'
|
||||
import { Task } from '@lit-labs/task'
|
||||
|
||||
import Photo from '/images/Meredith Monk (1974) Photo Lauretta Harris.jpg'
|
||||
|
||||
// components
|
||||
import '../components/Loading.js'
|
||||
import '../components/AudioCard.js'
|
||||
|
@ -27,7 +25,9 @@ class AudioView extends LitElement {
|
|||
const div = this.shadowRoot.querySelector('mm-audio-player')
|
||||
|
||||
div.addEventListener('transitionend', () => {
|
||||
this.selected = { ...detail, media: `${Router.route.path}/${detail.media}` }
|
||||
this.selected = {
|
||||
...detail
|
||||
}
|
||||
div.classList.remove('unloading')
|
||||
})
|
||||
|
||||
|
@ -49,10 +49,19 @@ class AudioView extends LitElement {
|
|||
const res = await fetch(`/data${Router.route.path}.json`)
|
||||
const json = await res.json()
|
||||
|
||||
this.tracks = json
|
||||
// start track (0 is not currently available)
|
||||
const idx = 1
|
||||
this.selected = { ...this.tracks[idx], idx, media: `${Router.route.path}/${this.tracks[idx].media}` }
|
||||
this.tracks = json.map(i => {
|
||||
i.media = `/media${Router.route.path}/${i.media}`
|
||||
i.image = i.image ? `/media${Router.route.path}/${i.image}` : ''
|
||||
|
||||
return i
|
||||
})
|
||||
|
||||
if (this.tracks.length > 0) {
|
||||
const idx = 0
|
||||
this.selected = {
|
||||
...this.tracks[idx], idx,
|
||||
}
|
||||
}
|
||||
},
|
||||
() => []
|
||||
)
|
||||
|
@ -70,21 +79,20 @@ class AudioView extends LitElement {
|
|||
<div class="scroll-items">
|
||||
${this._getAudio.render({
|
||||
pending: () => html`<mm-loading style="--fill-color: grey"></mm-loading>`,
|
||||
complete: () => html`${this.tracks.map((t, i) => html`
|
||||
complete: () => html`${this.tracks.length > 0 ? this.tracks.map((t, i) => html`
|
||||
<mm-acard
|
||||
idx=${i}
|
||||
icon=${t.album ? 'album' : 'play-circle'}
|
||||
?selected=${t.title == this.selected.title && t.details == this.selected.details}
|
||||
.details=${t}
|
||||
></mm-acard>`)}`,
|
||||
></mm-acard>`) : 'No tracks added for this category' }`,
|
||||
error: (err) => html`Error: ${err}`
|
||||
})}
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="player">
|
||||
<div class="player ${this.selected.tracks ? '' : 'single'}">
|
||||
<div>
|
||||
${this.selected?.tracks ? '' : html`<img class="bg-img" src=${Photo} />` }
|
||||
<mm-audio-player .details=${this.selected}></mm-audio-player>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -126,6 +134,13 @@ class AudioView extends LitElement {
|
|||
.player {
|
||||
position: relative;
|
||||
|
||||
&.single > div {
|
||||
background-image: url('/images/Meredith Monk (1974) Photo Lauretta Harris.jpg'), var(--green-gradient-400);
|
||||
background-position: center;
|
||||
background-size: 110%, 110%, cover;
|
||||
background-blend-mode: soft-light, screen;
|
||||
}
|
||||
|
||||
> div {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
|
|
|
@ -30,10 +30,6 @@ class ImageView extends LitElement {
|
|||
json.forEach(i => i.path = `/media${Router.route.path}/${i.media}`)
|
||||
|
||||
this.images = json
|
||||
this.selected = this.images[0]
|
||||
|
||||
console.log(this.selected)
|
||||
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
}
|
||||
|
@ -42,30 +38,54 @@ class ImageView extends LitElement {
|
|||
)
|
||||
|
||||
selectImage({ target }) {
|
||||
const { details } = target
|
||||
if (details?.title != this.selected?.title) {
|
||||
this.selected = details
|
||||
}
|
||||
console.log(target.details)
|
||||
const event = new CustomEvent('single-fullscreen-image', {
|
||||
bubbles: true, composed: true,
|
||||
detail: { ...target.details, src: `/media${Router.route.path}/${target.details.section}/${target.details.media}` }
|
||||
})
|
||||
|
||||
this.dispatchEvent(event)
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<mm-img-carousel .images=${this.images}></mm-img-carousel>
|
||||
<!-- <mm-img-carousel .images=${this.images}></mm-img-carousel> -->
|
||||
|
||||
<mm-hscroller>
|
||||
${this._getImages.render({ complete: () => this.images.map(i => html`
|
||||
<mm-vcard @click=${this.selectImage} .details=${i} ?selected=${i.title == this.selected?.title}></mm-vcard>
|
||||
`) })}
|
||||
</mm-hscroller>
|
||||
${this.images.length > 0 ?
|
||||
html`
|
||||
<div class="gallery">
|
||||
${this._getImages.render({ complete: () => this.images.map(
|
||||
section => html`
|
||||
<header class="section-header">
|
||||
<h3>${section.title}</h3>
|
||||
</header>
|
||||
<main>
|
||||
${section.images.map(
|
||||
i => html`
|
||||
<mm-vcard
|
||||
@click=${this.selectImage}
|
||||
.details=${ { ...i, section: section.media } }
|
||||
?selected=${i.title == this.selected?.title}
|
||||
>
|
||||
</mm-vcard>
|
||||
`)}
|
||||
</main>
|
||||
`
|
||||
) })}
|
||||
</div>
|
||||
` :
|
||||
html`<h2>No images added to the gallery</h2>`
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
static styles = [ css`${unsafeCSS(MainCSS)}`, css`
|
||||
:host {
|
||||
flex-grow: 1;
|
||||
display: grid;
|
||||
grid-template-rows: 1fr auto;
|
||||
gap: 0.5em;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
padding-inline: 1em;
|
||||
padding-block: 1em;
|
||||
}
|
||||
|
||||
mm-hscroller {
|
||||
|
@ -77,12 +97,34 @@ class ImageView extends LitElement {
|
|||
--color: var(--green-400, lime);
|
||||
}
|
||||
|
||||
header {
|
||||
padding-block-start: 1.5em;
|
||||
padding-block-end: 1em;
|
||||
font-size: 1.25em;
|
||||
border-bottom: 1px solid var(--green-400);
|
||||
margin-block-end: 1em;
|
||||
}
|
||||
|
||||
main {
|
||||
display: grid;
|
||||
gap: 0.75em;
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
grid-auto-rows: 10em;
|
||||
}
|
||||
|
||||
|
||||
.image {
|
||||
position: relative;
|
||||
inline-margin: auto;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
mm-image-carousel {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
}
|
||||
` ]
|
||||
}
|
||||
|
||||
|
||||
customElements.define('mm-images', ImageView)
|
||||
|
|
|
@ -44,7 +44,7 @@ class VideoView extends LitElement {
|
|||
<main>
|
||||
<aside>
|
||||
<h2>${this.selected.title}</h2>
|
||||
<p class="detail">${this.selected.detail}</p>
|
||||
<p class="details">${this.selected.details}</p>
|
||||
</aside>
|
||||
<mm-vplayer media='/media/${this.selected.media}' ?autoplay=${this.selected.autoplay}></mm-vplayer>
|
||||
</main>
|
||||
|
@ -55,7 +55,7 @@ class VideoView extends LitElement {
|
|||
complete: () => html`${this.films.map(t => html`
|
||||
<mm-vcard
|
||||
.details=${t}
|
||||
?selected=${t.title == this.selected.title && t.detail == this.selected.detail}
|
||||
?selected=${t.title == this.selected.title && t.details == this.selected.details}
|
||||
></mm-vcard>`
|
||||
)}`
|
||||
})}
|
||||
|
@ -68,7 +68,7 @@ class VideoView extends LitElement {
|
|||
flex-grow: 1;
|
||||
height: 100%;
|
||||
display: grid;
|
||||
grid-template-rows: 70% 30%;
|
||||
grid-template-rows: 1fr 0.55fr;
|
||||
gap: 0.25em;
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ class VideoView extends LitElement {
|
|||
margin-block-end: 0.2em;
|
||||
}
|
||||
|
||||
> .detail {
|
||||
> .details {
|
||||
line-height: 1.1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,12 @@ export default defineConfig({
|
|||
build: {
|
||||
sourcemap: true,
|
||||
target: [ 'esnext', 'edge100', 'firefox100', 'chrome100', 'safari18' ],
|
||||
rollupOptions: {
|
||||
external: [
|
||||
'scripts',
|
||||
'public/media'
|
||||
],
|
||||
},
|
||||
},
|
||||
server: {
|
||||
host: '0.0.0.0'
|
||||
|
|
Loading…
Reference in New Issue