## Added - Feed Media Enhancement with Media RSS namespace support - RSS enclosure, media:content, media:thumbnail elements - JSON Feed image field for first image - ADR-059: Full feed media standardization roadmap ## Fixed - Media display on homepage (was only showing on note pages) - Responsive image sizing with CSS constraints - Caption display (now alt text only, not visible) - Logging correlation ID crash in non-request contexts ## Documentation - Feed media design documents and implementation reports - Media display fixes design and validation reports - Updated ROADMAP with v1.3.0/v1.4.0 media plans 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
282 lines
9.5 KiB
Markdown
282 lines
9.5 KiB
Markdown
# ADR-059: Full Feed Media Standardization (Option 3)
|
|
|
|
## Status
|
|
Proposed (For v1.3.0 Backlog)
|
|
|
|
## Context
|
|
StarPunk v1.2.0 introduced media attachments for notes (images). The initial implementation embeds media as HTML in feed description fields. Option 2 (implemented in v1.2.x) adds Media RSS extension elements and JSON Feed image fields for better feed reader compatibility.
|
|
|
|
This ADR documents Option 3: Full Standardization, which provides comprehensive media support across all syndication formats, including video, audio, and advanced features. This is planned for v1.3.0 or later.
|
|
|
|
## Decision
|
|
Document the scope of "Full Standardization" for feed media support to be implemented in a future release. This option goes beyond Option 2's basic Media RSS support to include:
|
|
|
|
1. **Complete Media RSS Specification Support**
|
|
2. **Podcast RSS Support (RSS 2.0 enclosures for audio)**
|
|
3. **Video Support**
|
|
4. **Multiple Image Sizes/Thumbnails**
|
|
5. **Full JSON Feed 1.1 Media Compliance**
|
|
|
|
## Scope of Full Standardization
|
|
|
|
### 1. Complete Media RSS Implementation
|
|
|
|
**Research Required**: Full Media RSS specification at https://www.rssboard.org/media-rss
|
|
|
|
**Elements to Implement**:
|
|
- `<media:content>` with full attribute support:
|
|
- `url` (required) - Direct URL to media file
|
|
- `fileSize` - Size in bytes
|
|
- `type` - MIME type
|
|
- `medium` - Type: "image", "audio", "video", "document", "executable"
|
|
- `isDefault` - Boolean for default rendition
|
|
- `expression` - "full", "sample", "nonstop"
|
|
- `bitrate` - Kilobits per second
|
|
- `framerate` - Frames per second (video)
|
|
- `samplingrate` - Samples per second (audio)
|
|
- `channels` - Audio channels
|
|
- `duration` - Seconds
|
|
- `height` / `width` - Dimensions in pixels
|
|
- `lang` - RFC-3066 language code
|
|
|
|
- `<media:group>` - Container for multiple renditions of same content
|
|
- `<media:thumbnail>` - Multiple sizes with url, width, height, time
|
|
- `<media:title>` - Media title (type="plain" or "html")
|
|
- `<media:description>` - Media description (type="plain" or "html")
|
|
- `<media:keywords>` - Comma-separated keywords
|
|
- `<media:category>` - Categorization with scheme attribute
|
|
- `<media:credit>` - Credit attribution with role and scheme
|
|
- `<media:copyright>` - Copyright information
|
|
- `<media:rating>` - Content rating (scheme-based)
|
|
- `<media:hash>` - MD5/SHA-1 hash for integrity
|
|
- `<media:player>` - Embeddable player URL
|
|
|
|
**Effort Estimate**: 8-12 hours
|
|
|
|
### 2. Podcast RSS Support
|
|
|
|
**Research Required**:
|
|
- Apple Podcast RSS specification
|
|
- Google Podcast RSS requirements
|
|
- Podcast Index namespace (podcast:)
|
|
|
|
**Elements to Implement**:
|
|
- iTunes namespace (`xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"`):
|
|
- `<itunes:summary>` - Episode summary
|
|
- `<itunes:duration>` - Audio duration (HH:MM:SS)
|
|
- `<itunes:image>` - Episode artwork
|
|
- `<itunes:explicit>` - Content rating
|
|
- `<itunes:episode>` - Episode number
|
|
- `<itunes:season>` - Season number
|
|
- `<itunes:episodeType>` - "full", "trailer", "bonus"
|
|
- `<itunes:author>` - Author name
|
|
- `<itunes:owner>` - Owner contact
|
|
|
|
- Standard RSS `<enclosure>` for audio:
|
|
- `url` - Direct audio file URL
|
|
- `length` - File size in bytes
|
|
- `type` - MIME type (audio/mpeg, audio/mp4, etc.)
|
|
|
|
**Database Changes**:
|
|
- Add `duration` column to `note_media` table
|
|
- Add `media_type` enum (image, audio, video)
|
|
- Consider `podcast_metadata` table for series-level data
|
|
|
|
**Effort Estimate**: 10-16 hours
|
|
|
|
### 3. Video Support
|
|
|
|
**Research Required**:
|
|
- Video hosting considerations (storage, bandwidth)
|
|
- Supported formats (mp4, webm, ogg)
|
|
- Transcoding requirements
|
|
- Poster image generation
|
|
|
|
**Implementation Scope**:
|
|
- Accept video uploads via Micropub media endpoint
|
|
- Generate poster thumbnails automatically
|
|
- Include in Media RSS with proper video attributes:
|
|
- `medium="video"`
|
|
- `framerate`, `duration`, `bitrate`
|
|
- Associated `<media:thumbnail>` for poster
|
|
|
|
- HTML5 `<video>` element in feed description
|
|
- Consider video hosting limits (file size, duration)
|
|
|
|
**Database Changes**:
|
|
- Video-specific metadata in `media` table
|
|
- Poster image path
|
|
- Transcoding status (if needed)
|
|
|
|
**Effort Estimate**: 16-24 hours (significant)
|
|
|
|
### 4. Multiple Image Sizes (Thumbnails)
|
|
|
|
**Research Required**:
|
|
- Responsive image best practices
|
|
- WebP generation
|
|
- srcset/sizes patterns
|
|
|
|
**Implementation Scope**:
|
|
- Generate multiple sizes on upload:
|
|
- Thumbnail: 150x150 (square crop)
|
|
- Small: 320px width
|
|
- Medium: 640px width
|
|
- Large: 1280px width
|
|
- Original: preserved
|
|
|
|
- Store all sizes in `media_variants` table
|
|
- Include in Media RSS:
|
|
```xml
|
|
<media:group>
|
|
<media:content url="large.jpg" isDefault="true" width="1280" />
|
|
<media:content url="medium.jpg" width="640" />
|
|
<media:content url="small.jpg" width="320" />
|
|
</media:group>
|
|
<media:thumbnail url="thumb.jpg" width="150" height="150" />
|
|
```
|
|
|
|
- JSON Feed: Use `image` for default, include variants in `_starpunk` extension
|
|
|
|
**Database Changes**:
|
|
- `media_variants` table: media_id, variant_type, path, width, height, size_bytes
|
|
- Add `has_variants` boolean to `media` table
|
|
|
|
**Effort Estimate**: 8-12 hours
|
|
|
|
### 5. Full JSON Feed 1.1 Media Compliance
|
|
|
|
**Research Required**: JSON Feed 1.1 specification for extensions
|
|
|
|
**Implementation Scope**:
|
|
- Top-level `image` field (URL of first image, per spec)
|
|
- Top-level `banner_image` if applicable
|
|
- Item-level `image` field (main/featured image)
|
|
- Item-level `banner_image` for posts with banners
|
|
- Complete `attachments` array:
|
|
```json
|
|
{
|
|
"url": "https://example.com/media/image.jpg",
|
|
"mime_type": "image/jpeg",
|
|
"title": "Image caption",
|
|
"size_in_bytes": 245760,
|
|
"duration_in_seconds": null
|
|
}
|
|
```
|
|
- Audio attachments with `duration_in_seconds`
|
|
- Video attachments (if supported)
|
|
|
|
**Effort Estimate**: 4-6 hours
|
|
|
|
### 6. ATOM Feed Media Extensions
|
|
|
|
**Research Required**:
|
|
- ATOM Media extension namespace
|
|
- `<link rel="enclosure">` best practices
|
|
|
|
**Implementation Scope**:
|
|
- `<link rel="enclosure">` for each media item
|
|
- `type` attribute with MIME type
|
|
- `length` attribute with file size
|
|
- `title` attribute with caption
|
|
- Consider `<link rel="related">` for thumbnails
|
|
|
|
**Effort Estimate**: 3-5 hours
|
|
|
|
## Total Effort Estimate
|
|
|
|
| Feature | Minimum | Maximum |
|
|
|---------|---------|---------|
|
|
| Complete Media RSS | 8 hours | 12 hours |
|
|
| Podcast RSS Support | 10 hours | 16 hours |
|
|
| Video Support | 16 hours | 24 hours |
|
|
| Multiple Image Sizes | 8 hours | 12 hours |
|
|
| JSON Feed Compliance | 4 hours | 6 hours |
|
|
| ATOM Extensions | 3 hours | 5 hours |
|
|
| **Total** | **49 hours** | **75 hours** |
|
|
|
|
**Note**: Video support is the most complex feature and could be deferred to v1.4.0 "Media" release.
|
|
|
|
## Prerequisites
|
|
|
|
Before implementing Full Standardization:
|
|
|
|
1. **Option 2 Complete**: Basic Media RSS and JSON Feed `image` field
|
|
2. **Image Optimization**: ADR-058 image optimization strategy implemented
|
|
3. **Media Storage Architecture**: Clear path for large file storage
|
|
4. **Test Infrastructure**: Feed validation tests in place
|
|
|
|
## Implementation Phases
|
|
|
|
### Phase A: Enhanced Image Support (v1.3.0)
|
|
- Multiple image sizes/thumbnails
|
|
- Full Media RSS for images
|
|
- Enhanced JSON Feed attachments
|
|
- **Effort**: 12-18 hours
|
|
|
|
### Phase B: Audio Support (v1.3.x or v1.4.0)
|
|
- Podcast RSS implementation
|
|
- Audio duration extraction
|
|
- iTunes namespace
|
|
- **Effort**: 10-16 hours
|
|
|
|
### Phase C: Video Support (v1.4.0 "Media")
|
|
- Video upload handling
|
|
- Poster generation
|
|
- Video in feeds
|
|
- **Effort**: 16-24 hours
|
|
|
|
## Consequences
|
|
|
|
### Positive
|
|
- Best-in-class feed reader compatibility
|
|
- Podcast distribution capability
|
|
- Video content support
|
|
- Professional media syndication
|
|
- Future-proof architecture
|
|
|
|
### Negative
|
|
- Significant implementation effort (50-75 hours total)
|
|
- Increased storage requirements
|
|
- More complex feed generation
|
|
- Processing overhead for image variants
|
|
- Larger codebase to maintain
|
|
|
|
### Neutral
|
|
- Aligns with media-focused v1.4.0 roadmap
|
|
- Phased implementation possible
|
|
- Optional features can be configuration-gated
|
|
|
|
## Alternatives Considered
|
|
|
|
### Alternative 1: Minimal Enhancement (Option 2 Only)
|
|
Just implement basic Media RSS and JSON Feed image field.
|
|
- **Pros**: Low effort, immediate benefit
|
|
- **Cons**: Misses podcast/video opportunity
|
|
|
|
### Alternative 2: Third-Party Media Service
|
|
Use external service (Cloudinary, etc.) for media processing.
|
|
- **Pros**: Offloads complexity
|
|
- **Cons**: External dependency, cost, data ownership concerns
|
|
|
|
### Alternative 3: Plugin Architecture
|
|
Make media support pluggable for advanced features.
|
|
- **Pros**: Keeps core simple
|
|
- **Cons**: Added architectural complexity
|
|
|
|
## References
|
|
|
|
- [Media RSS Specification](https://www.rssboard.org/media-rss)
|
|
- [JSON Feed 1.1 Specification](https://jsonfeed.org/version/1.1)
|
|
- [Apple Podcast RSS Requirements](https://podcasters.apple.com/support/823-podcast-requirements)
|
|
- [Podcast Index Namespace](https://github.com/Podcastindex-org/podcast-namespace)
|
|
- [RSS 2.0 Enclosure Specification](https://www.rssboard.org/rss-specification#ltenclosuregtSubelementOfLtitemgt)
|
|
- [ADR-057: Media Attachment Model](/home/phil/Projects/starpunk/docs/decisions/ADR-057-media-attachment-model.md)
|
|
- [ADR-058: Image Optimization Strategy](/home/phil/Projects/starpunk/docs/decisions/ADR-058-image-optimization-strategy.md)
|
|
|
|
## Decision
|
|
This ADR documents the scope of Full Standardization (Option 3) for the project backlog. Implementation should be scheduled for v1.3.0 and v1.4.0 releases according to the phased approach outlined above.
|
|
|
|
**Immediate Action**: Implement Option 2 (ADR-060) for v1.2.x release.
|
|
**Future Action**: Review and refine this scope when scheduling v1.3.0 work.
|