fli_video 0.0.2 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.builders/generators/back/scripts/01-get-technical-design-and-feature-list.rb +32 -0
  3. data/.builders/generators/back/scripts/02-get-feature-list-and-components.rb +42 -0
  4. data/.builders/generators/back/scripts/03-get-structure.rb +104 -0
  5. data/.builders/generators/back/scripts/generated/application-structure.json +231 -0
  6. data/.builders/generators/back/scripts/generated/features-and-components.md +988 -0
  7. data/.builders/generators/back/scripts/generated/technical-design-and-features.md +424 -0
  8. data/.builders/klues/add_episode.klue +25 -0
  9. data/.builders/klues/change_chapter_name.klue +32 -0
  10. data/.builders/klues/create_chapter_video.klue +34 -0
  11. data/.builders/klues/create_project.klue +37 -0
  12. data/.builders/klues/empty_trash.klue +24 -0
  13. data/.builders/klues/episode_path.klue +77 -0
  14. data/.builders/klues/global_config.klue +31 -0
  15. data/.builders/klues/move_ecamm_file.klue +21 -0
  16. data/.builders/klues/move_to_trash.klue +35 -0
  17. data/.builders/klues/open_in_finder.klue +25 -0
  18. data/.builders/klues/project_config.klue +123 -0
  19. data/.builders/klues/project_meta_data_store.klue +28 -0
  20. data/.builders/klues/project_path.klue +77 -0
  21. data/.builders/klues/recording_file_watcher.klue +28 -0
  22. data/.builders/klues/recording_filename.klue +112 -0
  23. data/.builders/klues/restore_from_trash.klue +29 -0
  24. data/.builders/klues/switch_focus.klue +24 -0
  25. data/.builders/klues/text_to_speech.klue +29 -0
  26. data/.builders/klues/transcript_data_store.klue +28 -0
  27. data/.rubocop.yml +2 -0
  28. data/CHANGELOG.md +26 -0
  29. data/README.md +13 -20
  30. data/bin/fli_video +6 -0
  31. data/docs/feature-list.md +76 -0
  32. data/docs/generated/application-structure.json +53 -0
  33. data/docs/generated/features-and-components.md +993 -0
  34. data/docs/generated/technical-design-and-features.md +437 -0
  35. data/docs/technical-specifications.md +360 -0
  36. data/fli.rb +138 -0
  37. data/lib/fli_video/cli.rb +30 -0
  38. data/lib/fli_video/version.rb +1 -1
  39. data/package-lock.json +2 -2
  40. data/package.json +1 -1
  41. data/scripts/01-get-technical-design-and-feature-list.md +5 -0
  42. data/scripts/01-get-technical-design-and-feature-list.rb +39 -0
  43. data/scripts/02-get-feature-list-and-components.md +26 -0
  44. data/scripts/02-get-feature-list-and-components.rb +56 -0
  45. data/scripts/03-get-code-structure.md +33 -0
  46. data/scripts/03-get-code-structure.rb +73 -0
  47. metadata +41 -3
  48. data/README-features.md +0 -36
@@ -0,0 +1,31 @@
1
+ component :global_configuation do
2
+ pattern "Singleton"
3
+
4
+ desc "Access and apply global configuration settings for video asset management and state consistency."
5
+
6
+ comments <<~TEXT
7
+ Configuration file path: ~/.fli-video.json
8
+ - Automatically creates a configuration file if it does not exist.
9
+ - Responsible for reading and updating global configuration.
10
+ - Provides methods to manage folder paths and various settings.
11
+ TEXT
12
+
13
+ sample :configuration, <<~JSON
14
+ {
15
+ "folders": {
16
+ "ecamm-recordings": "~/Movies/Ecamm Live Recordings",
17
+ "project-root": "/Volumes/Expansion/Sync/tube-channels/a-cast/cast-active",
18
+ },
19
+ "settings": {
20
+ "focus-project-code": "a27",
21
+ },
22
+ }
23
+ JSON
24
+
25
+ method :set_folder(:key, :folder)
26
+ method :folder(:key)
27
+ method :set_setting(:key, :value)
28
+ method :setting(:key)
29
+ method :load
30
+ method :save
31
+ end
@@ -0,0 +1,21 @@
1
+ component :move_ecamm_file do
2
+ desc "Seamlessly transfer eCamm recordings to the current focused video or podcast episode recordings subfolder."
3
+
4
+ comments <<~TEXT
5
+ - Facilitates the transfer of eCamm recording files to the appropriate project's recording subfolder.
6
+ - Automatically identifies the current focused project or episode to ensure correct file placement.
7
+ - Handles the file transfer process, maintaining file integrity and updating any necessary metadata.
8
+ - Uses global configuration to determine eCamm recording folder location.
9
+ - Uses current project configuration to determine recording subfolder location.
10
+ - Aborts the transfer process if target folder does not exist.
11
+ TEXT
12
+
13
+ method :execute(:ecamm_file_name)
14
+
15
+ sample :move_ecamm_file_to_project, <<~RUBY
16
+ # Move an eCamm recording to the currently focused project's recordings subfolder
17
+ move_ecamm_file.execute('Ecamm Live Recording on 2023-08-25 at 14.51.58.mov')
18
+
19
+ # ~/video-projects/a20-ad-some-video/recordings/Ecamm Live Recording on 2023-08-25 at 14.51.58.mov
20
+ RUBY
21
+ end
@@ -0,0 +1,35 @@
1
+ component :move_to_trash do
2
+ desc "Move suboptimal video takes to '.trash' folder"
3
+
4
+ pattern "Command"
5
+
6
+ comments <<~TEXT
7
+ - Will trash a specific recording in a project folder.
8
+ - Will identify the last eCamm recording in a project folder if no specific recording is provided.
9
+ - Enhances project clarity and organization.
10
+ TEXT
11
+
12
+ constructure(:parent_project)
13
+
14
+ method :run(:file_name = nil)
15
+
16
+ sample :move_named_video_to_trash, <<~RUBY
17
+ project_path = ProjectPath.new('a27')
18
+
19
+ command = move_to_trash.new(project_path)
20
+
21
+ # Example of moving a specific suboptimal video take to the trash folder
22
+ command.run('01-a-introduction.mov')
23
+ # => "~/video-projects/a27-ac-categorize-mp4-CI/.trash/01-a-introduction.mov"
24
+ RUBY
25
+
26
+ sample :move_last_ecamm__video_to_trash, <<~RUBY
27
+ project_path = ProjectPath.new('a27')
28
+
29
+ command = move_to_trash.new(project_path)
30
+
31
+ # Example of moving the last suboptimal video take to the trash folder
32
+ command.run
33
+ # => "~/video-projects/a27-ac-categorize-mp4-CI/.trash/Ecamm Live Recording on 2023-08-25 at 14.51.58.mov
34
+ RUBY
35
+ end
@@ -0,0 +1,25 @@
1
+ component :open_in_finder do
2
+ desc "Quickly access video project and episode folders within the Finder."
3
+
4
+ pattern "Command"
5
+
6
+ comments <<~TEXT
7
+ - Provides shortcuts to open project and episode folders in the Finder.
8
+ - Enhances efficiency in navigating to specific video project locations.
9
+ - Streamlines the process of locating and managing video files and folders.
10
+ TEXT
11
+
12
+ constructor(:parent_project)
13
+
14
+ method :run
15
+
16
+ sample :access_project_in_finder, <<~RUBY
17
+ project_path = ProjectPath.new('a27')
18
+
19
+ command = open_in_finder.new(project_path)
20
+ # Opens the folder for project 'a27' in Finder
21
+
22
+ command.run
23
+ # Opens the folder for episode '01' of project 'a27' in Finder
24
+ RUBY
25
+ end
@@ -0,0 +1,123 @@
1
+ component :project_configuration do
2
+ desc "Manage project / episode settings and state."
3
+
4
+ pattern "Adapter"
5
+
6
+ comments <<~TEXT
7
+ Configuration file: .fv.json
8
+ - Handles settings for single videos or the episodes in a Podcast.
9
+ - Responsible for reading and updating settings.
10
+ - Supports state management for single video, episodes, recording and chapter progression.
11
+ - This class is a reflection of the configuration file and the folders and files it manages.
12
+
13
+ Project type: video
14
+ - A single video file.
15
+ - Supports recording and chapter progression
16
+
17
+ Project type: podcast
18
+ - Multiple video files known as episodes.
19
+ - Supports recording and chapter progression for each episode.
20
+
21
+ Infers project type from the presence of the "episodes" key.
22
+ Infers project name from the name of the folder containing the configuration file.
23
+ Infers episode name from the name of the folder containing the video file.
24
+ Keeps track of prefered chapter name for each chapter sequence.
25
+ TEXT
26
+
27
+ method :load
28
+ method :save
29
+ method :resync_project_files() # refreshes the configuration based on the file system
30
+ method :current_chapter() # if type == :video
31
+ method :current_episode() # if type == :podcast
32
+
33
+ data_object :project_config do
34
+ constructor(:json)
35
+
36
+ attribute :type # video, podcast
37
+ attribute :code
38
+ attribute :chapters # if type == :video
39
+ attribute :episodes # if type == :podcast
40
+ end
41
+
42
+ data_object :episode_config do
43
+ constructor(:json)
44
+
45
+ attribute :seq # episode number store as number, but displayed as 2 digit string
46
+ attribute :chapters
47
+ attribute :current # true if this is the current episode
48
+
49
+ method :current_chapter()
50
+ end
51
+
52
+ data_object :chapter_config do
53
+ constructor(:json)
54
+
55
+ attribute :seq
56
+ attribute :preferred_name
57
+ attribute :current # true if this is the current chapter
58
+ end
59
+
60
+ sample :configuration, :for_video, <<~JSON
61
+ {
62
+ "type": "video",
63
+ "code": "e28",
64
+ "chapters": [
65
+ {
66
+ seq: 1,
67
+ preferred_name: "intro"
68
+ },
69
+ {
70
+ seq: 2,
71
+ preferred_name: "example"
72
+ },
73
+ {
74
+ seq: 3,
75
+ preferred_name: "outro",
76
+ current: true
77
+ }
78
+ ]
79
+ }
80
+ JSON
81
+
82
+ sample :configuration, :for_podcast, <<~JSON
83
+ {
84
+ "type": "podcast",
85
+ "code": "e27",
86
+ "episodes": [
87
+ {
88
+ "seq": 1,
89
+ "chapters": [
90
+ {
91
+ "seq": 1,
92
+ "preferred_name": "introduction",
93
+ },
94
+ {
95
+ "seq": 2,
96
+ "preferred_name": "scenario",
97
+ "current": true
98
+ }
99
+ ]
100
+ },
101
+ {
102
+ "seq": 2,
103
+ "current": true,
104
+ "chapters": [
105
+ {
106
+ "seq": 1,
107
+ "preferred_name": "introduction",
108
+ },
109
+ {
110
+ "seq": 2,
111
+ "preferred_name": "scenario",
112
+ },
113
+ {
114
+ "seq": 3,
115
+ "preferred_name": "story",
116
+ "current": true
117
+ }
118
+ ]
119
+ }
120
+ ]
121
+ }
122
+ JSON
123
+ end
@@ -0,0 +1,28 @@
1
+ component :project_meta_data_store do
2
+ desc "Build a JSON datastore of project files with inferred metadata."
3
+
4
+ pattern "Command"
5
+
6
+ comments <<~TEXT
7
+ - Aggregates file data from project, episode, recording, chapter, and post-produced folders.
8
+ - Infers metadata from sources like KEYWORDS, transcripts, and other relevant data.
9
+ - Creates a comprehensive JSON datastore for the entire project.
10
+ - Facilitates advanced data analysis and management for the project.
11
+ - The extracted data can be used for automated post-production processes like keyword generation, B-roll prompts, chapter names, title slides, and time code markers for calls to action.
12
+ TEXT
13
+
14
+ constructor(:parent_project)
15
+
16
+ method :run
17
+
18
+ sample :build_project_metadata, <<~RUBY
19
+ project_path = ProjectPath.new('a27')
20
+
21
+ # Instantiate the component with the parent project
22
+ metadata_store = project_meta_data_store.new(project_path)
23
+
24
+ # Execute the process to aggregate files and infer metadata
25
+ metadata_store.run
26
+ # Output: '~/video-projects/a27-ac-categorize-mp4-CI/project_metadata.json'
27
+ RUBY
28
+ end
@@ -0,0 +1,77 @@
1
+ component :project_path do
2
+ desc "Construct project path using project code and deducing state based on existing folder name."
3
+
4
+ pattern "Adapter"
5
+
6
+ comments <<~TEXT
7
+ - Infers project path based on project code and existing folder name.
8
+ - Maintains state for project code, channel code, descriptive name, keywords and episodes.
9
+ - Uses global configuration to determine root folder.
10
+ - Uses existing folder name and keywords to build internal state.
11
+ - Provides method for building absolute, relative and sub folder.
12
+ - Provides method for building new path for rename operations.
13
+ - Provides list of associated episode paths.
14
+ - Stores state in an internal data object.
15
+ - Designed for building folder names, not create or modify actual directories.
16
+ TEXT
17
+
18
+ accessors :project_code, :channel_code, :project_name, :keywords, :project_path, :episodes
19
+
20
+ method :constructor(:project_code, channel_code: nil, project_name: nil, keywords: nil)
21
+ method :instance(:folder)
22
+
23
+ method :change_path(project_code: nil, channel_code: nil, project_name: nil, keywords: nil)
24
+
25
+ sample :create_project_path, <<~RUBY
26
+ # Create a new project path
27
+ project_path = ProjectPath.new('a27', channel_code: 'ac', project_name: 'categorize-mp4', keywords: ['CI'] )
28
+ project_path.project_path # => "~/video-projects/a27-ac-categorize-mp4-CI"
29
+ project_path.project_code # => "a27"
30
+ project_path.channel_code # => "ac"
31
+ project_path.project_name # => "categorize-mp4"
32
+ project_path.keywords # => "CI"
33
+ project_path.episodes.count # => 0
34
+ RUBY
35
+
36
+ sample :infer_project_path, <<~RUBY
37
+ # Infer project path based on project code and existing folder
38
+ project_path = ProjectPath.new('a27')
39
+ project_path.project_path # => "~/video-projects/a27-ac-categorize-mp4-CI"
40
+ project_path.project_code # => "a27"
41
+ project_path.channel_code # => "ac"
42
+ project_path.project_name # => "categorize-mp4"
43
+ project_path.keywords # => "CI"
44
+ project_path.episodes.count # => 2
45
+ RUBY
46
+
47
+ sample :rename_project_path, <<~RUBY
48
+ # Rename project path
49
+ project_path = ProjectPath.new('a27')
50
+
51
+ path1 = project_path.change_path(project_code: 'a28')
52
+ path1.project_path # => "~/video-projects/a28-ac-categorize-mp4-CI"
53
+ path2 = project_path.change_path(channel_code: 'ad', project_name: 'categorize-mp4-for-appydave')
54
+ path2.project_path # => "~/video-projects/a27-ad-categorize-mp4-for-appydave-CI"
55
+ path3 = project_path.change_path(keywords: [])
56
+ path3.project_path # => "~/video-projects/a27-ac-categorize-mp4"
57
+ RUBY
58
+
59
+ sample :next_project_code, <<~RUBY
60
+ # Get next project code
61
+ project_path = ProjectPath.new('a27')
62
+ project_path.next_project_code # => "a28"
63
+
64
+ project_path = ProjectPath.new('a99')
65
+ project_path.next_project_code # => "b00"
66
+ RUBY
67
+
68
+ sample :folder_to_project_path, <<~RUBY
69
+ # Convert folder to project path
70
+ project_path = ProjectPath.instance('~/video-projects/a27-ac-categorize-mp4-CI')
71
+ project_path.project_path # => "~/video-projects/a27-ac-categorize-mp4-CI"
72
+ project_path.project_code # => "a27"
73
+ project_path.channel_code # => "ac"
74
+ project_path.project_name # => "categorize-mp4"
75
+ project_path.keywords # => "CI"
76
+ RUBY
77
+ end
@@ -0,0 +1,28 @@
1
+ component :filewatch_processor do
2
+ desc "Automate file event responses, directing new recordings to current project folders."
3
+
4
+ pattern "Observer"
5
+
6
+ comments <<~TEXT
7
+ - Monitors new eCamm recordings file events.
8
+ - Automates the process of moving new recordings to specified project folders.
9
+ - Enhances content management by ensuring recordings are organized efficiently.
10
+ - Configurable to respond to different types of file events and target folders.
11
+ TEXT
12
+
13
+ method :watch(:folder_path, :event_type)
14
+
15
+ # Will move the file to current project's recordings folder
16
+ method :move_file
17
+
18
+ sample :automate_recording_organization, <<~RUBY
19
+ config = GlobalConfig.instance
20
+
21
+ # Watch a specific folder for new and existing recordings
22
+ filewatch_processor.watch(config.folders['ecamm-recordings'], '*.mov', :moved_file)
23
+
24
+ # Example usage
25
+ # When a new file is detected in Ecamm Live Recordings, it is automatically moved to the current project's recordings folder.
26
+ filewatch_processor.move_file
27
+ RUBY
28
+ end
@@ -0,0 +1,112 @@
1
+ component :recording_filename do
2
+ desc "Calculate the next video recording file name based on chapter sequence, part number, chapter name, and tags if available."
3
+
4
+ pattern "Adapter"
5
+
6
+ comments <<~TEXT
7
+ - File name construction for new and existing video recordings.
8
+ - Utilizes the chapter and part sequence for systematic naming.
9
+ - Incorporates the chapter name for descriptive clarity.
10
+ - Has support for tags in the file name to aid content identification and post-processing workflows.
11
+ - Set episode & project via the episode if recording belongs to an episode
12
+ - Set project if recording belongs to a project
13
+ - Parent returns episode || project
14
+ TEXT
15
+
16
+ accessors :chapter_seq, :part_seq, :chapter_name, :tags, :filename, :episode, :project, :parent
17
+
18
+ method :constructor(:chapter_seq, :part_seq, :chapter_name, tags: [], parent: nil)
19
+ method :instance(:full_path)
20
+
21
+ # Use the current chapter sequence if not provided
22
+ # Part sequence will increment based on the previous part letter in the chapter if not provided
23
+ # Chapter name will defaults to previous recording chapter name if not provided
24
+ method :next_filename(:previous_filename, chapter_name: nil, tags: [], chapter_seq: nil, part_seq: nil)
25
+ method :update_chapter_sequence(:current_chapter_seq, :new_chapter_seq)
26
+ method :resequence_chapters(:starting_chapter_seq)
27
+ method :update_tags(:new_tags)
28
+
29
+ sample :create_recording_filename, <<~RUBY
30
+ project_path = ProjectPath.new('a27')
31
+ project_path.project_path # => "~/video-projects/a27-ac-categorize-mp4-CI"
32
+
33
+ # Generate a filename for a new video recording
34
+ filename1 = RecordingFilename.new(1, 'a' 'introduction', tags: [], parent: project_path)
35
+ filename1.filename # => "01-a-introduction.mov"
36
+ filename1.chapter_seq # => 1
37
+ filename1.part_seq # => "a"
38
+ filename1.chapter_name # => "introduction"
39
+ filename1.tags # => []
40
+ filename1.full_path # => "~/video-projects/a27-ac-categorize-mp4-CI/01-a-introduction.mov"
41
+ RUBY
42
+
43
+ sample :next_recording_filename, <<~RUBY
44
+ filename1 = "~/video-projects/a27-ac-categorize-mp4-CI/01-a-introduction.mov"
45
+
46
+ project = ProjectConfig.new('a27')
47
+
48
+ # Class method to generate a filename for a new video recording
49
+ filename2 = RecordingFilename.next_filename(filename1, chapter_name: 'introduction-more-content', tags: ['GPTIMPROVE'])
50
+
51
+ # Fluent method to generate a filename for a new video recording
52
+ filename3 = filename2.next_filename(chapter_name: 'introduction')
53
+ filename4 = filename3.next_filename(tags: ['CTA'])
54
+
55
+ project.next_chapter('overview')
56
+
57
+ filename5 = RecordingFilename.next_filename(project.last_file)
58
+
59
+ project.next_chapter('scenario')
60
+
61
+ filename6 = RecordingFilename.next_filename(project.last_file, tags: ['TITLE'])
62
+
63
+ filename1.filename # => "01-a-introduction-GPTIMPROVE.mov" # Send transcription to GPT Bot for improvement
64
+ filename2.filename # => "01-b-introduction-more-content.mov"
65
+ filename3.filename # => "01-c-introduction.mov"
66
+ filename4.filename # => "01-d-introduction-CTA.mov" # Instruction for video editor to add a CTA
67
+ filename5.filename # => "02-a-overview.mov"
68
+ filename6.filename # => "03-a-scenario-TITLE.mov" # Instruction for video editor to add a title slide
69
+ RUBY
70
+
71
+ sample :file_to_recording_filename, <<~RUBY
72
+ # Convert absolute file to recording filename
73
+ filename = RecordingFilename.instance('~/video-projects/a27-ac-categorize-mp4-CI/01-a-introduction.mov')
74
+
75
+ filename.filename # => "01-a-introduction.mov"
76
+ filename.chapter_seq # => 1
77
+ filename.part_seq # => "a"
78
+ filename.chapter_name # => "introduction"
79
+ filename.tags # => []
80
+ filename.full_path # => "~/video-projects/a27-ac-categorize-mp4-CI/01-a-introduction.mov"
81
+ RUBY
82
+
83
+ sample :rename_recording_filename, <<~RUBY
84
+ filename = RecordingFilename.instance('~/video-projects/a27-ac-categorize-mp4-CI/01-a-introduction.mov')
85
+ filename.filename # => "01-a-introduction.mov"
86
+
87
+ filename.change_filename(chapter_name: 'introduction-trim-23s', tags: ['GPTDALE3'])
88
+ filename.filename # => "01-a-introduction-trim-23s-GPTDALE3.mov"
89
+ RUBY
90
+
91
+ sample :update_chapter_sequence, <<~RUBY
92
+ project_path = ProjectPath.new('a27')
93
+
94
+ # Update chapter sequence in a project
95
+ filename = RecordingFilename.new(2, 'b', 'overview', parent: project_path)
96
+ filename.update_chapter_sequence(2, 3)
97
+ filename.filename # => "03-b-overview.mov"
98
+ RUBY
99
+
100
+ sample :resequence_chapters, <<~RUBY
101
+ # Resequence chapters starting from a given sequence
102
+ filename.resequence_chapters(2)
103
+ # Adjusts chapter sequence of all subsequent chapters starting from '02'
104
+ RUBY
105
+
106
+ sample :update_tags, <<~RUBY
107
+ # Update tags for a recording
108
+ filename = RecordingFilename.new(1, 'a', 'introduction', tags: ['OLD_TAG'], parent: project_path)
109
+ filename.update_tags(['NEW_TAG'])
110
+ filename.filename # => "01-a-introduction-NEW_TAG.mov"
111
+ RUBY
112
+ end
@@ -0,0 +1,29 @@
1
+ component :restore_from_trash do
2
+ desc "Retrieve video takes from '.trash' folder and move them back to the project folder."
3
+
4
+ pattern "Command"
5
+
6
+ comments <<~TEXT
7
+ - Restores a specific recording from the trash to the project folder.
8
+ - If no specific recording is provided, restores the most recently trashed recording.
9
+ - Facilitates reconsideration or re-evaluation of previously discarded content.
10
+ TEXT
11
+
12
+ constructor(:parent_project)
13
+
14
+ method :run(:file_name)
15
+
16
+ sample :restore_from_trash, <<~RUBY
17
+ project_path = ProjectPath.new('a27')
18
+
19
+ command = undo_trash.new(project_path)
20
+
21
+ # Example of restoring a specific recording from the trash folder
22
+ command.run('01-a-introduction.mov')
23
+ # => "~/video-projects/a27-ac-categorize-mp4-CI/01-a-introduction.mov"
24
+
25
+ # Example of restoring the most recently trashed recording
26
+ command.run
27
+ # => "~/video-projects/a27-ac-categorize-mp4-CI/Ecamm Live Recording on 2023-08-25 at 14.51.58.mov"
28
+ RUBY
29
+ end
@@ -0,0 +1,24 @@
1
+ component :change_focus do
2
+ desc "Easily switch between different video projects or episodes to accommodate changing content priorities."
3
+
4
+ pattern "Interactor"
5
+
6
+ comments <<~TEXT
7
+ - Allows switching the focus to a different video project or a specific episode within a podcast.
8
+ - Video recordings belong to a specific project or episode and this interaction ensures that the correct project or episode is in focus.
9
+ - Ensures seamless transition and updates the working context to the selected project or episode.
10
+ - Maintains state consistency across switches using the global configuration.
11
+ TEXT
12
+
13
+ method :run(:project_code, episode_code: nil)
14
+
15
+ sample :switch_focus_to_video_project, <<~RUBY
16
+ # Switch focus to a different video project
17
+ change_focus.run('a20')
18
+ RUBY
19
+
20
+ sample :switch_focus_to_podcast_episode, <<~RUBY
21
+ # Switch focus to a specific episode within a podcast project
22
+ change_focus.run('a21', '02')
23
+ RUBY
24
+ end
@@ -0,0 +1,29 @@
1
+ component :text_to_speech do
2
+ desc "Transcribe spoken content to text and store in multiple transcription formats."
3
+
4
+ pattern "Command"
5
+
6
+ comments <<~TEXT
7
+ - Transcribes audio content from videos into text.
8
+ - Supports storing transcriptions in various formats for accessibility and further processing.
9
+ - Uses the transcript folder under the recording, chapter or post-production folder and stores the transcriptions in a subfolder called 'transcript'.
10
+ TEXT
11
+
12
+ constructor(:parent_project)
13
+
14
+ method :run(:recording_file, output_formats:)
15
+
16
+ sample :transcribe_audio_to_text, <<~RUBY
17
+ project_path = ProjectPath.new('a27')
18
+
19
+ # ~/video-projects/a27-ac-categorize-mp4-CI/01-a-introduction.mov
20
+ # Instantiate the component with the parent project
21
+ tts = text_to_speech.new(project_path)
22
+
23
+ # Execute the transcription against
24
+ tts.run('01-introduction.mov', output_formats: ['txt', 'srt', 'vtt', 'json', 'tsv'])
25
+
26
+ # Transcribes '01-introduction.mov' and stores the transcriptions in the specified formats
27
+ # Output: Transcriptions saved in '~/video-projects/a27-ac-categorize-mp4-CI/recordings/transcript/01-introduction.txt|srt|vtt|json|tsv'
28
+ RUBY
29
+ end
@@ -0,0 +1,28 @@
1
+ component :transcript_data_store do
2
+ desc "Build a JSON datastore of transcripts for an entire project."
3
+
4
+ pattern "Command"
5
+
6
+ comments <<~TEXT
7
+ - Aggregates transcripts from various project levels into a single JSON datastore.
8
+ - Scans project, episode, recording, chapter, and post-produced folders for existing transcripts.
9
+ - Facilitates easy access and management of transcript data across the entire project.
10
+ - Enhances data retrieval and analysis capabilities for the project's transcripts.
11
+ - Stores data in a JSON file called 'transcripts.json' in the project folder.
12
+ TEXT
13
+
14
+ constructor(:parent_project)
15
+
16
+ method :run
17
+
18
+ sample :build_transcript_datastore, <<~RUBY
19
+ project_path = ProjectPath.new('a27')
20
+
21
+ # Instantiate the component with the parent project
22
+ transcript_store = transcript_data_store.new(project_path)
23
+
24
+ # Execute the process to aggregate and store transcript data
25
+ transcript_store.run
26
+ # Output: '~/video-projects/a27-ac-categorize-mp4-CI/project_transcripts.json'
27
+ RUBY
28
+ end
data/.rubocop.yml CHANGED
@@ -14,6 +14,8 @@ AllCops:
14
14
  Exclude:
15
15
  - ".builders/**/*"
16
16
  - "spec/samples/**/*"
17
+ - "scripts/**/*"
18
+ - "fli.rb"
17
19
 
18
20
  Metrics/BlockLength:
19
21
  Exclude:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,29 @@
1
+ # [0.1.0](https://github.com/klueless-io/fli_video/compare/v0.0.2...v0.1.0) (2023-12-24)
2
+
3
+
4
+ ### Features
5
+
6
+ * project kickoff ([a3863cf](https://github.com/klueless-io/fli_video/commit/a3863cf712002497cb77a829b2b832a0f8d54a0b))
7
+ * starting projectx ([0680236](https://github.com/klueless-io/fli_video/commit/06802367b7a1cfa3b928b97e41031d1c24c41c9b))
8
+
9
+ ## [0.0.2](https://github.com/klueless-io/fli_video/compare/v0.0.1...v0.0.2) (2023-12-19)
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * downgrade sem ver ([34c7f77](https://github.com/klueless-io/fli_video/commit/34c7f77bf52b899cbc36e202b71ea9530177e9a7))
15
+ * naming issue ([b573d05](https://github.com/klueless-io/fli_video/commit/b573d056e044c8054ef1f98fc8219041efac86ab))
16
+ * package json issue ([efc9435](https://github.com/klueless-io/fli_video/commit/efc9435d829585db1fc27878f134f5f8b802f5a0))
17
+ * ruby 2.7 ([303d59f](https://github.com/klueless-io/fli_video/commit/303d59f49fd7cbc09e2ac0b2c89ba8538d3dd37b))
18
+ * testing semver1 ([f71b294](https://github.com/klueless-io/fli_video/commit/f71b2944c6bffa8c85859b247dced28f9cc61cdd))
19
+ * testing semver2 ([f0ea217](https://github.com/klueless-io/fli_video/commit/f0ea217416783452db4a0efee0df37ac64391bb1))
20
+ * testing semver3 ([c28ffa8](https://github.com/klueless-io/fli_video/commit/c28ffa8b428216807046acec74935e6fee6f710a))
21
+ * testing semver4 ([c1e260d](https://github.com/klueless-io/fli_video/commit/c1e260d069e88f72b4505dd52050305fd6de64cd))
22
+ * version fixed for semver ([c65bf64](https://github.com/klueless-io/fli_video/commit/c65bf64335b040ca96e6aab495f7b73cfeda4f8d))
23
+ * version fixed for semver ([484225f](https://github.com/klueless-io/fli_video/commit/484225ff32be5dc21a6e9c7231f73c59f6753ada))
24
+ * version fixed for semver ([1011cd9](https://github.com/klueless-io/fli_video/commit/1011cd90daf6631078b22be47c8a37265ab8b6f2))
25
+ * version normalization ([e50f6ac](https://github.com/klueless-io/fli_video/commit/e50f6acf3500ee1b5cc80cb57ea24823a017d905))
26
+
1
27
  ## [Unreleased]
2
28
 
3
29
  ## [0.1.0] - 2023-12-19