|
| 1 | +[[begin technical plan]] |
| 2 | + |
| 3 | +[[begin invocation]] |
| 4 | +We are going to do all of this from the linux command line. We are going to use |
| 5 | +the following command |
| 6 | + |
| 7 | +``` |
| 8 | +mediainfo --Output=JSON videofile.webm |
| 9 | +``` |
| 10 | + |
| 11 | +to create a json output of the file. From there we will use a linux pipe to feed |
| 12 | +the output json in a haskell execuable. |
| 13 | +[[end invocation]] |
| 14 | + |
| 15 | + |
| 16 | +[[begin haskell executable]] |
| 17 | +the haskell executable is build using cabal. it will make use of the aeson |
| 18 | +library to parse the json. it will make use of the fmt library to create a |
| 19 | +builder for the output. It will make use of optparse-applicative to get the |
| 20 | +file name of the video from user input, with a helpful cli based UI to respond |
| 21 | +to errors and help requests |
| 22 | +[[end haskell executable]] |
| 23 | + |
| 24 | +[[begin sample input 1]] |
| 25 | +{ |
| 26 | +"creatingLibrary":{"name":"MediaInfoLib","version":"24.12","url":"https://mediaarea.net/MediaInfo"}, |
| 27 | +"media":{"@ref":"/home/hippoid/videos/Rebuilding my NixOS config - Part 17: How to Use NixOS Specializations [fhE08-ZJ-Sk].webm","track":[{"@type":"General","VideoCount":"1", |
| 28 | +"AudioCount":"1", |
| 29 | +"MenuCount":"1", |
| 30 | +"FileExtension":"webm", |
| 31 | +"Format":"WebM", |
| 32 | +"Format_Version":"4", |
| 33 | +"FileSize":"117874810", |
| 34 | +"Duration":"975.408", |
| 35 | +"OverallBitRate":"966773", |
| 36 | +"FrameRate":"30.000", |
| 37 | +"FrameCount":"29261", |
| 38 | +"IsStreamable":"Yes", |
| 39 | +"File_Modified_Date":"2024-11-04 07:47:04 UTC", |
| 40 | +"File_Modified_Date_Local":"2024-11-04 01:47:04", |
| 41 | +"Encoded_Application":"Lavf61.7.100", |
| 42 | +"Encoded_Library":"Lavf61.7.100"},{"@type":"Video","StreamOrder":"0", |
| 43 | +"ID":"1", |
| 44 | +"UniqueID":"17333972104246241731", |
| 45 | +"Format":"VP9", |
| 46 | +"Format_Profile":"0", |
| 47 | +"CodecID":"V_VP9", |
| 48 | +"Duration":"975.366000000", |
| 49 | +"Width":"2560", |
| 50 | +"Height":"1440", |
| 51 | +"Sampled_Width":"2560", |
| 52 | +"Sampled_Height":"1440", |
| 53 | +"PixelAspectRatio":"1.000", |
| 54 | +"DisplayAspectRatio":"1.778", |
| 55 | +"FrameRate_Mode":"CFR", |
| 56 | +"FrameRate":"30.000", |
| 57 | +"FrameCount":"29261", |
| 58 | +"ColorSpace":"YUV", |
| 59 | +"ChromaSubsampling":"4:2:0", |
| 60 | +"BitDepth":"8", |
| 61 | +"Delay":"0.000", |
| 62 | +"Delay_Source":"Container", |
| 63 | +"Language":"en", |
| 64 | +"Default":"Yes", |
| 65 | +"Forced":"No", |
| 66 | +"colour_description_present":"Yes", |
| 67 | +"colour_description_present_Source":"Container", |
| 68 | +"colour_range":"Limited", |
| 69 | +"colour_range_Source":"Container / Stream", |
| 70 | +"colour_primaries":"BT.709", |
| 71 | +"colour_primaries_Source":"Container", |
| 72 | +"transfer_characteristics":"BT.709", |
| 73 | +"transfer_characteristics_Source":"Container", |
| 74 | +"matrix_coefficients":"BT.709", |
| 75 | +"matrix_coefficients_Source":"Container / Stream"},{"@type":"Audio","StreamOrder":"1", |
| 76 | +"ID":"2", |
| 77 | +"UniqueID":"17934552372420491549", |
| 78 | +"Format":"Opus", |
| 79 | +"CodecID":"A_OPUS", |
| 80 | +"Duration":"975.401000000", |
| 81 | +"Channels":"2", |
| 82 | +"ChannelPositions":"Front: L R", |
| 83 | +"ChannelLayout":"L R", |
| 84 | +"SamplingRate":"48000", |
| 85 | +"SamplingCount":"46819248", |
| 86 | +"BitDepth":"32", |
| 87 | +"Compression_Mode":"Lossy", |
| 88 | +"Delay":"0.007", |
| 89 | +"Delay_Source":"Container", |
| 90 | +"Video_Delay":"0.007", |
| 91 | +"Language":"en", |
| 92 | +"Default":"Yes", |
| 93 | +"Forced":"No"},{"@type":"Menu","extra":{"_00_00_00_000":"Introduction to NixOS Specializations","_00_01_04_000":"Setting Up Your First Specialization","_00_03_00_000":"Booting and Testing Specializations","_00_05_20_000":"Switching Between Specializations","_00_10_45_000":"Advanced Specialization Configurations","_00_10_54_000":"Practical Use Cases for Specializations","_00_13_35_000":"Checking Specialization Status","_00_15_21_000":"Conclusion and Final Thoughts"}}]} |
| 94 | +} |
| 95 | +[[end sample input 1]] |
| 96 | + |
| 97 | +[[begin sample output 1]] |
| 98 | +1 introduction to nixos specializations 00:00:00 |
| 99 | +2 setting up your first specialization 00:01:04 |
| 100 | +2 booting and testing specializations 00:03:00 |
| 101 | +4 switching between specializations 00:05:20 |
| 102 | +5 advanced specialization configurations 00:10:45 |
| 103 | +6 practical use cases for specializations 00:10:54 |
| 104 | +7 checking specialization status 00:13:35 |
| 105 | +8 conclusion and final thoughts 00:15:21 |
| 106 | +[[end sample input 1]] |
| 107 | + |
| 108 | +[[begin sample input 2]] |
| 109 | +{ |
| 110 | +"creatingLibrary":{"name":"MediaInfoLib","version":"24.12","url":"https://mediaarea.net/MediaInfo"}, |
| 111 | +"media":{"@ref":"/home/hippoid/videos/Improving Quality of Life with YubiKeys on NixOS [3CeXbONjIgE].webm","track":[{"@type":"General","VideoCount":"1", |
| 112 | +"AudioCount":"1", |
| 113 | +"MenuCount":"1", |
| 114 | +"FileExtension":"webm", |
| 115 | +"Format":"WebM", |
| 116 | +"Format_Version":"4", |
| 117 | +"FileSize":"182515611", |
| 118 | +"Duration":"1291.068", |
| 119 | +"OverallBitRate":"1130943", |
| 120 | +"FrameRate":"30.000", |
| 121 | +"FrameCount":"38732", |
| 122 | +"IsStreamable":"Yes", |
| 123 | +"File_Modified_Date":"2024-10-10 00:44:18 UTC", |
| 124 | +"File_Modified_Date_Local":"2024-10-09 19:44:18", |
| 125 | +"Encoded_Application":"Lavf61.7.100", |
| 126 | +"Encoded_Library":"Lavf61.7.100"},{"@type":"Video","StreamOrder":"0", |
| 127 | +"ID":"1", |
| 128 | +"UniqueID":"8363614795069664182", |
| 129 | +"Format":"VP9", |
| 130 | +"Format_Profile":"0", |
| 131 | +"CodecID":"V_VP9", |
| 132 | +"Duration":"1291.066000000", |
| 133 | +"Width":"2560", |
| 134 | +"Height":"1440", |
| 135 | +"Sampled_Width":"2560", |
| 136 | +"Sampled_Height":"1440", |
| 137 | +"PixelAspectRatio":"1.000", |
| 138 | +"DisplayAspectRatio":"1.778", |
| 139 | +"FrameRate_Mode":"CFR", |
| 140 | +"FrameRate":"30.000", |
| 141 | +"FrameCount":"38732", |
| 142 | +"ColorSpace":"YUV", |
| 143 | +"ChromaSubsampling":"4:2:0", |
| 144 | +"BitDepth":"8", |
| 145 | +"Delay":"0.000", |
| 146 | +"Delay_Source":"Container", |
| 147 | +"Language":"en", |
| 148 | +"Default":"Yes", |
| 149 | +"Forced":"No", |
| 150 | +"colour_description_present":"Yes", |
| 151 | +"colour_description_present_Source":"Container", |
| 152 | +"colour_range":"Limited", |
| 153 | +"colour_range_Source":"Container / Stream", |
| 154 | +"colour_primaries":"BT.709", |
| 155 | +"colour_primaries_Source":"Container", |
| 156 | +"transfer_characteristics":"BT.709", |
| 157 | +"transfer_characteristics_Source":"Container", |
| 158 | +"matrix_coefficients":"BT.709", |
| 159 | +"matrix_coefficients_Source":"Container / Stream"},{"@type":"Audio","StreamOrder":"1", |
| 160 | +"ID":"2", |
| 161 | +"UniqueID":"3357261617258377654", |
| 162 | +"Format":"Opus", |
| 163 | +"CodecID":"A_OPUS", |
| 164 | +"Duration":"1291.061000000", |
| 165 | +"Channels":"2", |
| 166 | +"ChannelPositions":"Front: L R", |
| 167 | +"ChannelLayout":"L R", |
| 168 | +"SamplingRate":"48000", |
| 169 | +"SamplingCount":"61970928", |
| 170 | +"BitDepth":"32", |
| 171 | +"Compression_Mode":"Lossy", |
| 172 | +"Delay":"0.007", |
| 173 | +"Delay_Source":"Container", |
| 174 | +"Video_Delay":"0.007", |
| 175 | +"Language":"en", |
| 176 | +"Default":"Yes", |
| 177 | +"Forced":"No"},{"@type":"Menu","extra":{"_00_00_00_000":"Introduction","_00_01_19_000":"YubiKey overview","_00_01_54_000":"Assumptions","_00_02_14_000":"Yubico apps we'll be using","_00_02_46_000":"Creating a YubiKey module","_00_04_26_000":"Setting a FIDO PIN for YubiKeys","_00_05_15_000":"Generating ssh keys for YubiKeys","_00_06_41_000":"Storing pub keys in nix-config and symlinking them","_00_07_53_000":"Declaring pub keys as authorized_keys","_00_08_32_000":"Storing private keys in nix-secrets, auto-extraction, and symlinking","_00_09_23_000":"Confirming public and private key symlinking","_00_10_35_000":"Handling multiple YubiKeys without the wait time","_00_13_13_000":"Associating the keys to hosts using ssh match blocks","_00_14_29_000":"Testing a passwordless ssh connection","_00_14_47_000":"Touch-based sudo using U2F","_00_16_58_000":"Testing touch-based sudo","_00_17_47_000":"Extras: Notifications when touch is requested","_00_19_08_000":"Extras: Git commit signing","_00_19_32_000":"Extras: LUKS2 decryption","_00_20_32_000":"Extras: Improved physical access to your YubiKey","_00_21_03_000":"Thank you!"}}]} |
| 178 | +} |
| 179 | +} |
| 180 | +[[end sample input 2]] |
| 181 | + |
| 182 | +[[begin sample output 2]] |
| 183 | +Menu |
| 184 | +1 introduction 00:00:00.000 |
| 185 | +2 yubikey overview 00:01:19.000 |
| 186 | +3 assumptions 00:01:54.000 |
| 187 | +4 yubico apps we'll be using 00:02:14.000 |
| 188 | +6 creating a yubikey module 00:02:46.000 |
| 189 | +7 setting a fido pin for yubikeys 00:04:26.000 |
| 190 | +8 generating ssh keys for yubikeys 00:05:15.000 |
| 191 | +9 storing pub keys in nix-config and symlinking them 00:06:41.000 |
| 192 | +10 declaring pub keys as authorized_keys 00:07:53.000 |
| 193 | +11 storing private keys in nix-secrets, auto-extraction, and symlinking 00:08:32.000 |
| 194 | +12 confirming public and private key symlinking 00:09:23.000 |
| 195 | +13 handling multiple yubikeys without the wait time 00:10:35.000 |
| 196 | +14 associating the keys to hosts using ssh match blocks 00:13:13.000 |
| 197 | +15 testing a passwordless ssh connection 00:14:29.000 |
| 198 | +16 touch-based sudo using u2f 00:14:47.000 |
| 199 | +17 testing touch-based sudo 00:16:58.000 |
| 200 | +18 extras: notifications when touch is requested 00:17:47.000 |
| 201 | +19 extras: git commit signing 00:19:08.000 |
| 202 | +20 extras: luks2 decryption 00:19:32.000 |
| 203 | +21 extras: improved physical access to your yubikey 00:20:32.000 |
| 204 | +22 thank you! 00:21:03.000 |
| 205 | +[[end sample input 2]] |
| 206 | + |
| 207 | +[[end technical plan]] |
0 commit comments