id: https://nde.nl/ontology/hc/class/VideoPost name: video_post_class title: Video Post Class imports: - linkml:types - ./SocialMediaPost - ./SocialMediaPostTypes - ../slots/language - ../slots/has_aspect_ratio # REMOVED 2026-01-15: ../slots/available_caption_languages - migrated to has_available_caption_language # MIGRATED 2026-01-22: caption_available → has_or_had_caption + Caption per slot_fixes.yaml feedback - ../slots/has_or_had_caption - ./Caption # REMOVED 2026-01-18: ../slots/comment_author - migrated to has_or_had_author + Author (Rule 53) - ../slots/has_or_had_author - ./Author # REMOVED 2026-01-22: ../slots/comment_author_channel_id - migrated to has_or_had_identifier + DigitalPlatformUserIdentifier (Rule 53) - ./DigitalPlatformUserIdentifier # REMOVED 2026-01-18: ../slots/comment_id - migrated to has_or_had_identifier + Identifier (Rule 53) # REMOVED 2026-01-18: ../slots/comment_count - migrated to has_or_had_quantity + Quantity (Rule 53) # REMOVED 2026-01-22: ../slots/comment_like_count - migrated to is_or_was_appreciated + AppreciationEvent (Rule 53) - ../slots/is_or_was_appreciated - ./AppreciationEvent # REMOVED 2026-01-18: ../slots/comment_published_at - migrated to temporal_extent + TimeSpan (Rule 53) - ../slots/temporal_extent - ./TimeSpan - ../slots/has_or_had_comment_reply # REMOVED 2026-01-22: ../slots/comment_reply_count - migrated to has_or_had_reply + CommentReply (Rule 53) - ../slots/has_or_had_reply - ./CommentReply # REMOVED 2026-01-18: ../slots/comment_text - migrated to has_or_had_content + Content (Rule 53) - ../slots/has_or_had_content - ./Content # REMOVED 2026-01-18: ../slots/comment_updated_at - migrated to was_last_updated_at + Timestamp (Rule 53) - ../slots/was_last_updated_at - ./Timestamp # REMOVED 2026-01-22: ../slots/comments_fetched - migrated to was_fetched_at + is_or_was_part_of_total + SourceCommentCount (Rule 53) - ../slots/was_fetched_at - ../slots/is_or_was_part_of_total - ./SourceCommentCount # MIGRATED 2026-01-23: default_audio_language, default_language → has_or_had_language + Language + has_or_had_status + Status - ../slots/has_or_had_language - ./Language - ../slots/has_or_had_status - ./Status - ../slots/is_or_was_dismissed - ./DismissalEvent # MIGRATED 2026-01-25: duration → has_or_had_time_interval + TimeInterval (Rule 53) - ../slots/has_or_had_time_interval - ./TimeInterval - ../slots/duration - ../slots/favorite_count # MIGRATED 2026-01-22: frame_rate → has_or_had_quantity + Quantity + has_or_had_unit + Unit (Rule 53) - ../slots/has_or_had_unit - ./Unit - ../slots/is_embeddable - ../slots/is_licensed_content - ../slots/is_made_for_kid - ../slots/like_count - ../slots/live_broadcast_content - ../slots/metrics_observed_at - ../slots/specificity_annotation - ../slots/has_or_had_score # was: template_specificity - migrated per Rule 53 (2026-01-17) # REMOVED - migrated to has_or_had_identifier with VideoCategoryIdentifier (2026-01-14, Rule 53) # - ../slots/video_category_id - ../slots/has_or_had_identifier - ./Identifier - ./VideoCategoryIdentifier # REMOVED 2026-01-18: ../slots/comment_id - migrated to has_or_had_identifier + Identifier (Rule 53) - ../slots/has_or_had_comment # was: video_comment - migrated per Rule 53 (2025-01-15) - ../slots/has_or_had_quantity - ./Quantity # MIGRATED 2026-01-15: ../slots/view_count → ../slots/has_or_had_quantity per Rule 53 - ./SpecificityAnnotation - ./TemplateSpecificityScore # was: TemplateSpecificityScores - migrated per Rule 53 (2026-01-17) - ./TemplateSpecificityType - ./TemplateSpecificityTypes # MIGRATED 2026-01-24: definition → has_or_had_resolution + Resolution (Rule 53) - ../slots/has_or_had_resolution - ./Resolution - ../slots/has_available_caption_language - ../enums/VideoDefinitionEnum - ../enums/LiveBroadcastStatusEnum prefixes: linkml: https://w3id.org/linkml/ hc: https://nde.nl/ontology/hc/ schema: http://schema.org/ dcterms: http://purl.org/dc/terms/ prov: http://www.w3.org/ns/prov# crm: http://www.cidoc-crm.org/cidoc-crm/ skos: http://www.w3.org/2004/02/skos/core# as: https://www.w3.org/ns/activitystreams# wd: http://www.wikidata.org/entity/ default_prefix: hc classes: VideoPost: is_a: SocialMediaPost class_uri: as:Video abstract: false description: 'Concrete class for video content with platform-specific properties. **DEFINITION**: VideoPost is a specialized SocialMediaPost for video content. It extends the base post class with video-specific slots for duration, resolution, captions, and engagement metrics. **EXTENDS**: SocialMediaPost This class adds: - Video technical properties (duration, definition, aspect ratio) - Caption and subtitle availability - Engagement metrics (views, likes, comments) - Platform-specific fields (YouTube category, live broadcast status) - Temporal markers (chapters, segments) **ONTOLOGY MAPPINGS**: | Property | Activity Streams | Schema.org | |----------|------------------|------------| | Class | as:Video | schema:VideoObject | | duration | as:duration | schema:duration | | definition | - | schema:videoQuality | | caption | - | schema:caption | | view_count | - | schema:interactionStatistic (via Quantity) | **PLATFORM SUPPORT**: | Platform | Duration Limit | Resolution | Captions | |----------|----------------|------------|----------| | YouTube | 12 hours (verified) | Up to 8K | VTT, SRT | | Vimeo | Varies by plan | Up to 8K | VTT, SRT | | Facebook | 4 hours | Up to 4K | Auto-generated | | TikTok | 10 minutes | 1080p | Auto-generated | | Instagram Reels | 90 seconds | 1080p | Auto-generated | **HERITAGE INSTITUTION USE CASES**: | Content Type | Typical Duration | Platform | |--------------|------------------|----------| | Virtual tours | 10-30 min | YouTube | | Conservation docs | 5-20 min | YouTube, Vimeo | | Curator interviews | 15-60 min | YouTube | | Object spotlights | 2-5 min | YouTube, Instagram | | Short clips | 15-60 sec | TikTok, Reels | | Live recordings | 30-120 min | YouTube | **METRICS OBSERVATION**: Video metrics (views, likes, comments) are observational data that change constantly. Each metric reading should include: - `metrics_observed_at`: When metrics were recorded - `retrieval_timestamp`: When API call was made **RELATIONSHIP TO VideoPostType**: - VideoPost is a **concrete post instance** with video content - VideoPostType is a **type classification** for categorizing posts - A VideoPost typically has `post_types: [VideoPostType]` - But may also have multiple types: `[LiveStreamPostType, VideoPostType]` **CAPTION AND SUBTITLE DISTINCTION**: Related classes for textual content derived from video: - VideoSubtitle: Time-coded text (SRT/VTT format) - VideoTranscript: Full text without timestamps - VideoAnnotation: Computer vision derived content See VideoTextContent hierarchy for detailed modeling. ' exact_mappings: - as:Video - schema:VideoObject close_mappings: - crm:E73_Information_Object related_mappings: - wikidata:Q34508 - wikidata:Q604644 slots: - has_aspect_ratio - has_available_caption_language # MIGRATED 2026-01-22: caption_available → has_or_had_caption + Caption per slot_fixes.yaml feedback - has_or_had_caption # REMOVED 2026-01-18: comment_count - migrated to has_or_had_quantity + Quantity (Rule 53) # REMOVED 2026-01-22: comments_fetched - migrated to was_fetched_at + is_or_was_part_of_total + SourceCommentCount (Rule 53) - was_fetched_at - is_or_was_part_of_total # MIGRATED 2026-01-23: default_audio_language, default_language → has_or_had_language + has_or_had_status (Rule 53) - has_or_had_language - has_or_had_status # MIGRATED 2026-01-24: definition → has_or_had_resolution + Resolution (Rule 53) - has_or_had_resolution - is_or_was_dismissed # MIGRATED 2026-01-25: duration → has_or_had_time_interval (Rule 53) - has_or_had_time_interval - favorite_count # REMOVED 2026-01-22: frame_rate - migrated to has_or_had_quantity + Quantity + Unit (Rule 53) - is_embeddable - is_licensed_content - is_made_for_kid - like_count - live_broadcast_content - metrics_observed_at - specificity_annotation - has_or_had_score # was: template_specificity - migrated per Rule 53 (2026-01-17) # REMOVED - migrated to has_or_had_identifier (2026-01-14, Rule 53) # - video_category_id - has_or_had_identifier - has_or_had_comment # was: video_comment - migrated per Rule 53 (2025-01-15) - has_or_had_quantity slot_usage: # MIGRATED 2026-01-25: duration → has_or_had_time_interval + TimeInterval (Rule 53) has_or_had_time_interval: range: TimeInterval required: false inlined: true description: | Video duration. MIGRATED from duration (ISO 8601 string) to TimeInterval class. examples: - value: duration_value: PT10M59S duration_description: 10 minutes and 59 seconds description: Video duration - value: duration_value: PT1H30M duration_description: 1 hour 30 minutes description: Long format duration # MIGRATED 2026-01-24: definition → has_or_had_resolution + Resolution (Rule 53) has_or_had_resolution: range: Resolution required: false inlined: true description: | Video resolution/quality information. MIGRATED from 'definition' slot per slot_fixes.yaml (Rule 53). Uses Resolution class with resolution_class, width, height. examples: - value: resolution_class: hd width: 1920 height: 1080 aspect_ratio: "16:9" description: Full HD 1080p video - value: resolution_class: "4k" width: 3840 height: 2160 description: 4K UHD video - value: resolution_class: sd description: Standard definition (simple enum for backward compatibility) has_aspect_ratio: range: string required: false examples: - value: '16:9' description: Standard widescreen - value: '9:16' description: Vertical format for Shorts/Reels # MIGRATED 2026-01-22: frame_rate → has_or_had_quantity + Quantity + has_or_had_unit + Unit (Rule 53) # frame_rate: # range: float # required: false # examples: # - value: 30.0 # description: 30 frames per second # MIGRATED 2026-01-22: caption_available → has_or_had_caption + Caption per slot_fixes.yaml feedback has_or_had_caption: range: Caption multivalued: true inlined: true required: false description: | Structured caption/subtitle information for this video. MIGRATED from caption_available per slot_fixes.yaml (Rule 53, 2026-01-22). Caption class provides language, format, and availability metadata. examples: - value: is_available: true language: en caption_format: closed_caption description: English closed captions available - value: is_available: true language: nl caption_format: VTT caption_url: https://example.org/video/captions_nl.vtt description: Dutch subtitles in VTT format - value: is_available: false language: null description: No captions available (migrated from caption_available false) # MIGRATED 2026-01-23: default_language, default_audio_language → has_or_had_language + Language + has_or_had_status + Status (Rule 53) has_or_had_language: description: | MIGRATED from default_language and default_audio_language per slot_fixes.yaml (Rule 53, 2026-01-23). Language information for video content using structured Language class. Use has_or_had_status to distinguish default/primary languages. **MODELING PATTERN**: - For content language: Language with is_primary: true or has_or_had_status: "content_language" - For audio language: Language with has_or_had_status: "audio_language" - Multiple languages supported via multivalued slot range: Language inlined: true multivalued: true required: false examples: - value: language_code: "nl" language_name: "Dutch" is_primary: true description: Dutch as primary content language (migrated from default_language) - value: language_code: "nl" language_name: "Dutch" description: Dutch audio track (migrated from default_audio_language) - value: language_code: "en" language_name: "English" is_primary: false description: English as secondary/subtitle language has_or_had_status: description: | MIGRATED 2026-01-23 to support default_language, default_audio_language distinction. Status tracking for language designations (primary, default, audio, content). Uses Status class for structured status representation. range: Status inlined: true multivalued: true required: false examples: - value: status_type: "default_content_language" status_value: "nl" description: Default content language is Dutch - value: status_type: "default_audio_language" status_value: "nl" description: Default audio language is Dutch has_available_caption_language: range: string multivalued: true required: false examples: - value: - nl - en - de description: Captions available in Dutch, English, German has_or_had_quantity: range: Quantity inlined: true multivalued: true description: | Quantified metrics for video content. RULE 53: Replaces deprecated view_count, comment_count, and frame_rate with structured Quantity class supporting measurement unit and temporal extent for point-in-time observation. MIGRATED SLOTS: - view_count → Quantity with has_or_had_measurement_unit: VIEW (2026-01-15) - comment_count → Quantity with has_or_had_measurement_unit: COMMENT (2026-01-18) - frame_rate → Quantity with has_or_had_unit: "frames per second" (2026-01-22) examples: - value: quantity_value: 132 quantity_type: VIEW_COUNT has_or_had_measurement_unit: has_or_had_type: VIEW temporal_extent: begin_of_the_begin: "2025-12-01T23:16:22Z" description: 132 views at observation time - value: quantity_value: 42 quantity_type: ENGAGEMENT_COUNT has_or_had_measurement_unit: has_or_had_type: COMMENT temporal_extent: begin_of_the_begin: "2025-12-01T23:16:22Z" description: 42 comments at observation time (migrated from comment_count) - value: quantity_value: 30.0 quantity_type: FRAME_RATE has_or_had_unit: unit_value: "frames per second" unit_uri: "qudt:FPS" description: 30 frames per second (migrated from frame_rate, 2026-01-22) - value: quantity_value: 24.0 quantity_type: FRAME_RATE has_or_had_unit: unit_value: "fps" has_or_had_label: - label_text: "frames per second" description: Cinema standard 24fps like_count: range: integer required: false minimum_value: 0 examples: - value: 2 description: 2 likes at observation time is_or_was_dismissed: range: DismissalEvent required: false multivalued: true inlined: true description: >- Dismissal or dislike metrics. MIGRATED from dislike_count (2026-01-26). examples: - value: has_or_had_quantity: quantity_value: 0 has_or_had_unit: has_or_had_label: "dislike" description: No dislikes at observation time # REMOVED 2026-01-18: comment_count - migrated to has_or_had_quantity + Quantity (Rule 53) # comment_count: # range: integer # required: false # minimum_value: 0 # examples: # - value: 0 # description: No comments at observation time favorite_count: range: integer required: false minimum_value: 0 metrics_observed_at: range: datetime required: false examples: - value: '2025-12-01T23:16:22.294232+00:00' description: Metrics observed December 1, 2025 # MIGRATED from video_category_id (2026-01-14, Rule 53) # video_category_id: # range: string # required: false # examples: # - value: '22' # description: 'YouTube: People & Blogs' # - value: '27' # description: 'YouTube: Education' has_or_had_identifier: description: Video category identifier (migrated from video_category_id) range: VideoCategoryIdentifier multivalued: true required: false inlined: true examples: - value: '{"has_or_had_code": "27", "category_name": "Education", "platform": "YouTube"}' description: 'YouTube: Education category' live_broadcast_content: range: LiveBroadcastStatusEnum required: false examples: - value: none description: Standard video (not live) - value: live description: Currently broadcasting is_licensed_content: range: boolean required: false is_embeddable: range: boolean required: false is_made_for_kid: range: boolean required: false # MIGRATED 2026-01-22: comments_fetched → was_fetched_at + is_or_was_part_of_total + SourceCommentCount (Rule 53) # comments_fetched: # range: integer # required: false # minimum_value: 0 # examples: # - value: 0 # description: No comments fetched was_fetched_at: description: | MIGRATED from comments_fetched per slot_fixes.yaml (Rule 53, 2026-01-22). Timestamp when comments were fetched from the video platform API. range: Timestamp inlined: true required: false examples: - value: has_or_had_timestamp: "2025-12-01T23:16:22Z" description: Comments fetched at observation time is_or_was_part_of_total: description: | MIGRATED from comments_fetched per slot_fixes.yaml (Rule 53, 2026-01-22). Structured count metadata showing fetched vs total comments. range: SourceCommentCount inlined: true required: false examples: - value: fetched_count: 100 total_count: 500 fetch_complete: false source_api: "youtube_data_api_v3" description: 100 of 500 comments fetched from YouTube API - value: fetched_count: 0 description: No comments fetched (minimal) has_or_had_comment: # was: video_comment - migrated per Rule 53 (2025-01-15) range: VideoComment multivalued: true required: false inlined: true description: | Comments on this video post. MIGRATED from video_comment slot per slot_fixes.yaml (Rule 53, 2025-01-15). comments: - Extends SocialMediaPost with video-specific properties - Maps to as:Video and schema:VideoObject - Metrics are observational - always include metrics_observed_at - Caption availability signals but not content (see VideoSubtitle) - YouTube is primary platform for heritage institution video content see_also: - https://www.w3.org/ns/activitystreams#Video - https://schema.org/VideoObject - https://developers.google.com/youtube/v3/docs/videos VideoComment: class_uri: schema:Comment description: 'A comment on a video post. Models user-generated comments with author, text, timestamp, and engagement metrics. Supports nested reply threads. ' exact_mappings: - schema:Comment - as:Note slots: # MIGRATED 2026-01-18: comment_author → has_or_had_author + Author (Rule 53) - has_or_had_author # MIGRATED 2026-01-22: comment_author_channel_id → has_or_had_identifier + DigitalPlatformUserIdentifier (Rule 53) # NOTE: has_or_had_identifier already present - used for both comment_id and comment_author_channel_id # REMOVED 2026-01-18: comment_id - migrated to has_or_had_identifier + Identifier (Rule 53) - has_or_had_identifier # MIGRATED 2026-01-22: comment_like_count → is_or_was_appreciated + AppreciationEvent (Rule 53) - is_or_was_appreciated # REMOVED 2026-01-18: comment_published_at - migrated to temporal_extent + TimeSpan (Rule 53) - temporal_extent - has_or_had_comment_reply # MIGRATED 2026-01-22: comment_reply_count → has_or_had_reply + CommentReply (Rule 53) - has_or_had_reply # REMOVED 2026-01-18: comment_text - migrated to has_or_had_content + Content (Rule 53) - has_or_had_content # REMOVED 2026-01-18: comment_updated_at - migrated to was_last_updated_at + Timestamp (Rule 53) - was_last_updated_at - specificity_annotation - has_or_had_score # was: template_specificity - migrated per Rule 53 (2026-01-17) slot_usage: # MIGRATED 2026-01-18: comment_id → has_or_had_identifier + Identifier (Rule 53/56) has_or_had_identifier: description: | MIGRATED from comment_id per slot_fixes.yaml (Rule 53/56, 2026-01-18). Unique identifier for the comment (YouTube comment ID). Uses Identifier class for structured identifier representation. range: Identifier inlined: true required: true examples: - value: identifier_scheme: youtube_comment_id identifier_value: "UgzK1234abcdefgh" description: YouTube comment identifier # REMOVED 2026-01-18: comment_author - migrated to has_or_had_author + Author (Rule 53) # MIGRATED 2026-01-18: comment_author → has_or_had_author + Author (Rule 53) # MIGRATED 2026-01-22: comment_author_channel_id is now captured via Author.has_or_had_identifier (Rule 53) has_or_had_author: description: | MIGRATED from comment_author per slot_fixes.yaml (Rule 53, 2026-01-18). UPDATED 2026-01-22: Now also captures comment_author_channel_id via nested identifier. Display name of comment author plus optional platform user identifier. Uses Author class for structured author representation. Platform channel ID captured via has_or_had_identifier → DigitalPlatformUserIdentifier. range: Author inlined: true required: true examples: - value: has_or_had_name: "Visitor123" description: Comment author display name only - value: has_or_had_name: "MuseumFan2024" has_or_had_identifier: - identifier_scheme: youtube_channel_id identifier_value: "UCsT0YIqwnpJCM-mx7-gSA4Q" platform_type: "youtube" platform_user_id: "UCsT0YIqwnpJCM-mx7-gSA4Q" description: Comment author with YouTube channel ID (migrated from comment_author_channel_id) # MIGRATED 2026-01-22: comment_author_channel_id → has_or_had_identifier + DigitalPlatformUserIdentifier (Rule 53) # NOTE: has_or_had_identifier slot_usage updated above to handle BOTH comment_id AND comment_author_channel_id # The Author class already has has_or_had_identifier slot, so channel_id can be linked via: # has_or_had_author: # has_or_had_identifier: # - identifier_scheme: youtube_channel_id # identifier_value: "UC1234..." # platform_type: "youtube" # MIGRATED 2026-01-18: comment_text → has_or_had_content + Content (Rule 53/56) has_or_had_content: description: | MIGRATED from comment_text per slot_fixes.yaml (Rule 53/56, 2026-01-18). Full text content of the comment. Uses Content class with has_or_had_description for the actual text. range: Content inlined: true required: true examples: - value: has_or_had_description: "Great video about the collection!" description: Comment content using Content class # MIGRATED 2026-01-18: comment_published_at → temporal_extent + TimeSpan (Rule 53/56) temporal_extent: description: | MIGRATED from comment_published_at per slot_fixes.yaml (Rule 53/56, 2026-01-18). When comment was originally posted. Uses TimeSpan class for structured temporal representation. range: TimeSpan inlined: true required: true examples: - value: begin_of_the_begin: "2025-01-14T10:30:00Z" description: Comment published timestamp # MIGRATED 2026-01-18: comment_updated_at → was_last_updated_at + Timestamp (Rule 53/56) was_last_updated_at: description: | MIGRATED from comment_updated_at per slot_fixes.yaml (Rule 53/56, 2026-01-18). When comment was last edited. Uses Timestamp class for structured temporal representation. range: Timestamp inlined: true required: false examples: - value: has_or_had_timestamp: "2025-01-15T10:30:00Z" has_or_had_precision: second description: Comment last updated timestamp # MIGRATED 2026-01-22: comment_like_count → is_or_was_appreciated + AppreciationEvent (Rule 53) is_or_was_appreciated: description: | MIGRATED from comment_like_count per slot_fixes.yaml (Rule 53, 2026-01-22). Appreciation metrics (likes) for this comment. Uses AppreciationEvent class for structured representation. range: AppreciationEvent inlined: true inlined_as_list: true required: false examples: - value: appreciation_type: "like" appreciation_count: 42 description: Comment with 42 likes - value: appreciation_type: "like" has_or_had_quantity: numeric_value: 100 has_or_had_unit: unit_label: "likes" description: Structured like count with Quantity # MIGRATED 2026-01-22: comment_reply_count → has_or_had_reply + CommentReply (Rule 53) has_or_had_reply: description: | MIGRATED from comment_reply_count per slot_fixes.yaml (Rule 53, 2026-01-22). Reply metrics for this comment. Uses CommentReply class for structured representation. range: CommentReply inlined: true inlined_as_list: true required: false examples: - value: reply_count: 5 reply_type: "comment_reply" description: Comment with 5 replies - value: reply_count: 0 description: Comment with no replies - value: reply_count: 12 has_or_had_quantity: numeric_value: 12 has_or_had_unit: unit_label: "replies" description: Structured reply count with Quantity has_or_had_comment_reply: range: VideoComment multivalued: true required: false inlined: true