Skip to content
Back to skills

Export

ASecurity

Export media collection to platform-specific formats (Plex, Jellyfin, MPD, mobile, archival)

  • 211 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 21, 2026
ai-agentsgobashperformance

Security analysis

A100/100

Scanned September 21, 2026

npx -y skills add jmagly/ai-writing-guide --skill export --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Export?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Export
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/jmagly-export-13cd6454/badge)](https://www.skillsdirectory.com/skills/jmagly-export-13cd6454)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
namespace: aiwg
name: export
platforms: [all]
description: Export media collection to platform-specific formats (Plex, Jellyfin, MPD, mobile, archival)
commandHint:
  argumentHint: --profile <plex|jellyfin|mpd|mobile|archival> <collection_path> <output_path> [--max-size <GB>] [--transcode]
  allowedTools: Bash, Read, Write, Glob, Grep
  model: haiku
  category: media-curator
  modelRole: efficiency
  modelTier: economy
---

# Export Media Collection

Export a curated media collection to platform-specific formats with appropriate transcoding, metadata, and directory structures.

## Purpose

Users consume media across diverse platforms, each with different format requirements, metadata standards, and organizational conventions. This command transforms a curated collection into the optimal structure for each target platform.

## Platform Profiles

### Plex Profile

**Formats:**
- Audio: FLAC (preferred), MP3 (320kbps), M4A (AAC)
- Video: MP4 (H.264/H.265), MKV
- Artwork: Embedded + `folder.jpg` in album directory

**Directory Structure:**
```
Music/
├── Artist Name/
│   ├── Album Name (Year)/
│   │   ├── folder.jpg
│   │   ├── 01 - Track Title.flac
│   │   ├── 02 - Track Title.flac
│   │   └── ...
│   └── Videos/
│       └── Video Title.mp4
```

**YAML Spec:**
```yaml
profile: plex
audio_formats: [flac, mp3, m4a]
video_formats: [mp4, mkv]
artwork:
  embedded: true
  folder_jpg: true
  max_resolution: 1500x1500
directory_pattern: "{artist}/{album} ({year})/{track:02d} - {title}.{ext}"
video_directory: "{artist}/Videos/{title}.{ext}"
metadata:
  prefer_embedded: true
  id3v2_version: 2.4
```

### Jellyfin Profile

**Formats:**
- Audio: FLAC (preferred), Opus, MP3
- Video: MP4, MKV, WebM
- Artwork: Embedded + `folder.jpg` + `artist.jpg`
- NFO: Supported for rich metadata

**Directory Structure:**
```
Music/
├── Artist Name/
│   ├── artist.jpg
│   ├── artist.nfo
│   ├── Album Name (Year)/
│   │   ├── folder.jpg
│   │   ├── album.nfo
│   │   ├── 01 - Track Title.flac
│   │   └── ...
│   └── Videos/
│       ├── Video Title.mp4
│       └── Video Title.nfo
```

**YAML Spec:**
```yaml
profile: jellyfin
audio_formats: [flac, opus, mp3]
video_formats: [mp4, mkv, webm]
artwork:
  embedded: true
  folder_jpg: true
  artist_jpg: true
  max_resolution: 1500x1500
nfo_files:
  album: true
  artist: true
  video: true
directory_pattern: "{artist}/{album} ({year})/{track:02d} - {title}.{ext}"
video_directory: "{artist}/Videos/{title}.{ext}"
metadata:
  prefer_embedded: true
  id3v2_version: 2.4
```

### MPD Profile

**Formats:**
- Audio: FLAC (preferred), Opus, MP3
- Artwork: `folder.jpg` in album directory

**Directory Structure:**
```
Music/
├── Artist Name/
│   └── Album Name/
│       ├── folder.jpg
│       ├── 01 - Track Title.flac
│       └── ...
```

**YAML Spec:**
```yaml
profile: mpd
audio_formats: [flac, opus, mp3]
artwork:
  embedded: true
  folder_jpg: true
  max_resolution: 1000x1000
directory_pattern: "{artist}/{album}/{track:02d} - {title}.{ext}"
metadata:
  prefer_embedded: true
  id3v2_version: 2.4
scanning:
  auto_rescan: true
  watch_mode: inotify
```

### Mobile Profile

**Formats:**
- Audio: Opus (preferred, 128-192kbps), M4A (AAC), MP3
- Video: MP4 (H.264, max 720p)
- Artwork: Embedded, max 500x500

**Size Constraints:**
- Transcode high-res audio to save space
- Limit video resolution
- Budget-aware export (stop when size limit reached)

**YAML Spec:**
```yaml
profile: mobile
audio_formats: [opus, m4a, mp3]
audio_quality:
  opus: 128k
  m4a: 192k
  mp3: 192k
video_formats: [mp4]
video_quality:
  max_resolution: 720p
  codec: h264
  bitrate: 1500k
artwork:
  embedded: true
  max_resolution: 500x500
transcode:
  always: true
  source_formats: [flac, wav, alac]
size_budget:
  enabled: true
  prioritize_by: importance
directory_pattern: "{artist}/{album}/{track:02d} - {title}.{ext}"
```

### Archival Profile

**Formats:**
- Audio: FLAC, WAV (no lossy formats)
- Video: MKV (preserve original quality)
- Checksums: SHA256SUMS
- Provenance: PROVENANCE.jsonld

**Directory Structure:**
```
Archive/
├── Artist Name/
│   ├── Album Name (Year)/
│   │   ├── 01 - Track Title.flac
│   │   ├── ...
│   │   ├── SHA256SUMS
│   │   ├── PROVENANCE.jsonld
│   │   └── folder.jpg
│   └── MANIFEST.json
```

**YAML Spec:**
```yaml
profile: archival
audio_formats: [flac, wav]
video_formats: [mkv]
preserve:
  original_filenames: true
  source_metadata: true
  acquisition_dates: true
checksums:
  algorithm: sha256
  filename: SHA256SUMS
provenance:
  format: jsonld
  filename: PROVENANCE.jsonld
  include_source_urls: true
  include_timestamps: true
manifest:
  per_album: false
  per_artist: true
  format: json
directory_pattern: "{artist}/{album} ({year})/{original_filename}"
```

## Transcoding Commands

### Audio Transcoding

**FLAC to Opus:**
```bash
ffmpeg -i input.flac -c:a libopus -b:a 128k -vn output.opus
```

**FLAC to MP3:**
```bash
ffmpeg -i input.flac -c:a libmp3lame -b:a 320k -id3v2_version 4 output.mp3
```

**Opus to MP3:**
```bash
ffmpeg -i input.opus -c:a libmp3lame -b:a 192k -id3v2_version 4 output.mp3
```

**Preserve Metadata:**
```bash
ffmpeg -i input.flac -c:a libopus -b:a 128k -vn -map_metadata 0 output.opus
```

### Video Transcoding

**4K to 1080p:**
```bash
ffmpeg -i input.mkv -vf scale=1920:1080 -c:v libx264 -crf 23 -c:a copy output.mp4
```

**1080p to 720p (mobile):**
```bash
ffmpeg -i input.mp4 -vf scale=1280:720 -c:v libx264 -crf 23 -b:v 1500k -c:a aac -b:a 128k output.mp4
```

**Extract Audio Only:**
```bash
ffmpeg -i video.mp4 -vn -c:a libopus -b:a 192k audio.opus
```

### Artwork Processing

**Resize Artwork:**
```bash
ffmpeg -i folder.jpg -vf scale=500:500:force_original_aspect_ratio=decrease -q:v 2 folder_mobile.jpg
```

**Extract Artwork from Audio:**
```bash
ffmpeg -i track.flac -an -vcodec copy folder.jpg
```

**Embed Artwork into Audio:**
```bash
ffmpeg -i track.flac -i folder.jpg -map 0:a -map 1:v -c:a copy -id3v2_version 4 -metadata:s:v title="Album cover" -metadata:s:v comment="Cover (front)" output.flac
```

## NFO File Generation

### Album NFO Template (Jellyfin/Kodi)

```xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<album>
  <title>{album_title}</title>
  <artist>{artist_name}</artist>
  <year>{release_year}</year>
  <genre>{genre}</genre>
  <style>{style}</style>
  <mood>{mood}</mood>
  <label>{label}</label>
  <releasedate>{release_date}</releasedate>
  <rating>{rating}</rating>
  <userrating>{user_rating}</userrating>
  <review>{review}</review>
  <musicbrainzalbumid>{mbid}</musicbrainzalbumid>
  <thumb aspect="thumb">{artwork_url}</thumb>
</album>
```

## Size-Budgeted Export (Mobile)

When exporting to mobile devices with limited storage:

1. **Calculate Space Budget:**
   - Parse `--max-size` parameter
   - Convert to bytes
   - Reserve 10% buffer for filesystem overhead

2. **Prioritize Content:**
   - Sort by importance score (frequency * rating * recency)
   - Essential albums first
   - Deep cuts last

3. **Transcode to Mobile Formats:**
   - FLAC → Opus 128kbps
   - High-res video → 720p H.264
   - Resize artwork to 500x500

4. **Track Running Total:**
   - Sum file sizes as files are added
   - Stop when budget exhausted
   - Generate report of included/excluded content

5. **Export Algorithm:**
```bash
budget_bytes=$(( max_size_gb * 1024 * 1024 * 1024 * 9 / 10 ))
total_bytes=0

while read -r file importance; do
  file_size=$(stat -f%z "$file" 2>/dev/null || stat -c%s "$file")

  if (( total_bytes + file_size > budget_bytes )); then
    echo "Budget exhausted. Stopping export." >&2
    break
  fi

  # Transcode and copy
  transcode_and_copy "$file" "$output_dir"
  total_bytes=$(( total_bytes + file_size ))
done < <(prioritized_file_list)
```

## Archival Export

### Preserve Original Formats

Never transcode. Copy files as-is to preserve quality and authenticity.

### Generate SHA-256 Checksums

```bash
cd "$album_dir"
find . -type f -not -name "SHA256SUMS" -exec sha256sum {} \; > SHA256SUMS
```

### Record Provenance

Create `PROVENANCE.jsonld` per W3C PROV standard:

```json
{
  "@context": "https://www.w3.org/ns/prov",
  "entity": "urn:aiwg:media:album:{mbid}",
  "wasGeneratedBy": {
    "activity": "urn:aiwg:activity:acquisition:{timestamp}",
    "time": "{iso8601_timestamp}",
    "wasAssociatedWith": "urn:aiwg:agent:media-curator"
  },
  "wasDerivedFrom": [
    {
      "entity": "{source_url}",
      "type": "download",
      "time": "{acquisition_date}"
    }
  ],
  "atLocation": "{file_path}",
  "hadPrimarySource": "{authoritative_source}"
}
```

### Generate Manifest

Per-artist `MANIFEST.json` listing all albums, tracks, formats, and checksums:

```json
{
  "artist": "Artist Name",
  "albums": [
    {
      "title": "Album Name",
      "year": 1973,
      "tracks": [
        {
          "number": 1,
          "title": "Track Title",
          "file": "01 - Track Title.flac",
          "format": "flac",
          "checksum": "sha256:abc123..."
        }
      ]
    }
  ],
  "export_date": "{iso8601_timestamp}",
  "profile": "archival"
}
```

## Workflow

### 1. Select Profile

Parse `--profile` argument. Load corresponding YAML spec.

### 2. Validate Source Collection

- Scan collection directory
- Verify files exist and are readable
- Check format compatibility with target profile

### 3. Create Output Directory Structure

Based on profile's `directory_pattern`:

```bash
mkdir -p "$output_dir/{artist}/{album}"
```

### 4. Transcode If Needed

Check if source format matches target profile. If not, transcode:

```bash
if [[ "$source_ext" == "flac" ]] && [[ "$target_profile" == "mobile" ]]; then
  ffmpeg -i "$source" -c:a libopus -b:a 128k -map_metadata 0 "$target"
fi
```

### 5. Copy/Move Files

```bash
cp -a "$source" "$destination"
```

Or move if `--move` flag set.

### 6. Embed Metadata

Ensure all required metadata is embedded per profile spec.

### 7. Generate Supplementary Files

- NFO files (Jellyfin profile)
- SHA256SUMS (archival profile)
- PROVENANCE.jsonld (archival profile)
- folder.jpg, artist.jpg (Plex/Jellyfin profiles)

### 8. Report

```
Export complete: Plex profile
Source: /media/source/Artist Name
Destination: /media/plex/Music/Artist Name
Files exported: 142
Total size: 3.2 GB
Transcoded: 0
Copied: 142
```

## Examples

### Export to Plex

```bash
/export --profile plex ~/Music/Archive/Pink\ Floyd /media/plex/Music
```

### Export to Mobile with Size Limit

```bash
/export --profile mobile ~/Music/Archive /sdcard/Music --max-size 32 --transcode
```

### Archival Export

```bash
/export --profile archival ~/Music/Curated /backup/Music/Archive
```

## Error Handling

- Missing source files: Report and skip
- Insufficient disk space: Abort with clear message
- Transcode failures: Log error, optionally skip or abort
- Permission denied: Report file path and required permissions

## Performance Considerations

- Parallel transcoding: Use GNU parallel or xargs -P for multi-core systems
- Progress reporting: Update every N files or every M seconds
- Disk I/O: Batch operations to minimize seeks
- Memory: Stream large files instead of loading into memory

## References

- @$AIWG_ROOT/agentic/code/addons/aiwg-utils/rules/human-authorization.md — Seek explicit authorization before overwriting existing export targets
- @$AIWG_ROOT/agentic/code/frameworks/media-curator/skills/curate/SKILL.md — Orchestration skill that invokes export as the final curation phase
- @$AIWG_ROOT/agentic/code/frameworks/media-curator/skills/assemble/SKILL.md — Assembly skill used before export to prepare media collections
- @$AIWG_ROOT/agentic/code/frameworks/media-curator/skills/integrity-verification/SKILL.md — Verify exported files match source checksums

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…