Documentation
¶
Overview ¶
Package media provides media processing analytics and bandwidth monitoring for S3 and CloudFront usage.
Index ¶
- Constants
- Variables
- func DecodeBlurhash(hash string, width, height int) (image.Image, error)
- func EnsureFilenameHasExtension(filename, contentType string) (string, error)
- func GenerateBlurhash(img image.Image, componentX, componentY int) (string, error)
- func GenerateBlurhashFromBytes(data []byte, mimeType string) (string, error)
- func GetDefaultBlurhash() string
- func IsAudioCodecExported(codec string) bool
- func IsVideoCodecExported(codec string) bool
- func ProcessImage(data []byte, mimeType string) (map[string]*ProcessedImage, error)
- func StripEXIF(data []byte, mimeType string) ([]byte, error)
- type BandwidthAnalytics
- type BandwidthReport
- type BandwidthUsage
- type CloudFrontLogEntry
- type CloudWatchEnhancedStreamingService
- func (s *CloudWatchEnhancedStreamingService) GetOptimalQuality(ctx context.Context, mediaID, userRegion string) (string, error)
- func (s *CloudWatchEnhancedStreamingService) GetRealConcurrentMetrics(ctx context.Context, mediaID string, totalViews int64) (int64, error)
- func (s *CloudWatchEnhancedStreamingService) GetRealGeographicData(ctx context.Context, mediaID string, totalViews int64) (map[string]int64, error)
- func (s *CloudWatchEnhancedStreamingService) GetRealQualityBreakdown(ctx context.Context, mediaID string, totalViews int64) (map[string]int64, error)
- type CostBreakdown
- type CostProjection
- type CostRecommendation
- type DASHManifest
- type DASHTrack
- type DataPoint
- type HLSManifest
- type HLSVariant
- type ImageSize
- type MP4Atom
- type MediaUsage
- type ProcessedImage
- type RegionUsage
- type StreamingAnalytics
- type StreamingEvent
- type StreamingService
- type StreamingURL
- type UserCost
- type VideoMetadata
- type VideoMetadataParser
Constants ¶
const ( FormatJPEG = "jpeg" FormatPNG = "png" FormatGIF = "gif" FormatWebP = "webp" )
Image format constants
const ( ProtocolHLS = "HLS" ProtocolDASH = "DASH" )
Streaming protocol constants
const ( Resolution720p = "720p" Resolution1080p = "1080p" Resolution480p = "480p" Resolution360p = "360p" )
Video resolution constants
Variables ¶
var ( ErrNoQualityMetrics = errors.InsufficientHistoricalData(1) ErrNoGeographicMetrics = errors.InsufficientHistoricalData(1) ErrGetMetric = errors.FailedToGet("metric", stdErrors.New("failed to get metric")) ErrNoDataPoints = errors.InsufficientHistoricalData(1) ErrGetMetricWithDim = errors.FailedToGet("metric with dimension", stdErrors.New("failed to get metric with dimension")) ErrNoDataPointsWithDim = errors.InsufficientHistoricalData(1) )
CloudWatch Enhanced Streaming errors
var ( ErrAWSConfigLoad = errors.ConnectionFailed("AWS config", stdErrors.New("failed to load AWS config")) ErrLogFilesListing = errors.FailedToList("log files", stdErrors.New("failed to list log files")) ErrLogFileRetrieval = errors.FailedToGet("log file", stdErrors.New("failed to retrieve log file")) ErrMetricDataSubmission = errors.ProcessingFailed("metric data submission", stdErrors.New("metric data submission failed")) ErrBandwidthUsageRetrieval = errors.FailedToGet("bandwidth usage", stdErrors.New("failed to retrieve bandwidth usage")) ErrBandwidthUsageStorage = errors.FailedToStore("bandwidth usage", stdErrors.New("failed to store bandwidth usage")) ErrRealtimeMetricSubmission = errors.ProcessingFailed("realtime metric submission", stdErrors.New("realtime metric submission failed")) )
Analytics errors
var ( ErrMoovAtomParseFailed = errors.NewValidationError("validation", "failed to parse moov atom") ErrAtomSizeTooLarge = errors.NewValidationError("validation", "atom size too large") ErrInvalidAtomSize = errors.NewValidationError("validation", "invalid atom size") ErrAtomExtendsFile = errors.NewValidationError("validation", "atom extends beyond file") ErrMvhdAtomParseFailed = errors.NewValidationError("validation", "failed to parse mvhd") ErrUnsupportedMvhdVersion = errors.NewValidationError("validation", "unsupported mvhd version") ErrTkhdAtomParseFailed = errors.NewValidationError("validation", "failed to parse tkhd") ErrUnsupportedTkhdVersion = errors.NewValidationError("validation", "unsupported tkhd version") ErrMoovAtomNotFound = errors.NewValidationError("validation", "moov atom not found") ErrExtendedSizeIncomplete = errors.NewValidationError("validation", "incomplete extended size atom") ErrMvhdAtomTooSmall = errors.NewValidationError("validation", "mvhd atom too small") ErrMvhdV0AtomIncomplete = errors.NewValidationError("validation", "mvhd v0 atom incomplete") ErrMvhdV1AtomIncomplete = errors.NewValidationError("validation", "mvhd v1 atom incomplete") ErrTkhdAtomTooSmall = errors.NewValidationError("validation", "tkhd atom too small") ErrTkhdV0AtomIncomplete = errors.NewValidationError("validation", "tkhd v0 atom incomplete") ErrTkhdV1AtomIncomplete = errors.NewValidationError("validation", "tkhd v1 atom incomplete") ErrHdlrAtomTooSmall = errors.NewValidationError("validation", "hdlr atom too small") ErrStsdAtomTooSmall = errors.NewValidationError("validation", "stsd atom too small") ErrStsdEntryIncomplete = errors.NewValidationError("validation", "stsd entry incomplete") ErrVideoMetadataParsingFailed = errors.NewValidationError("validation", "video metadata parsing failed, populated with fallback values") )
Video metadata parsing errors
var ( ErrSignURL = errors.NewValidationError("validation", "failed to sign URL") ErrInvalidURL = errors.NewValidationError("validation", "invalid URL") ErrCreateSignature = errors.NewValidationError("validation", "failed to create signature") ErrRecordStreamingEvent = errors.NewValidationError("validation", "failed to record streaming event") ErrCreateSession = errors.NewValidationError("validation", "failed to create session") ErrGetSession = errors.NewValidationError("validation", "failed to get session") ErrUpdateSession = errors.NewValidationError("validation", "failed to update session") ErrEndSession = errors.NewValidationError("validation", "failed to end session") ErrQueryUserSessions = errors.NewValidationError("validation", "failed to query user sessions") ErrScanMediaSessions = errors.NewValidationError("validation", "failed to scan media sessions") ErrCleanupExpiredSessions = errors.NewValidationError("validation", "failed to cleanup expired sessions") )
Streaming service errors
var ( ErrBlurhashEncode = errors.NewValidationError("validation", "failed to encode blurhash") ErrImageDecode = errors.NewValidationError("validation", "failed to decode image") ErrBlurhashDecode = errors.NewValidationError("validation", "failed to decode blurhash") )
Blurhash errors
var ( ErrImageDecodeProcess = errors.NewValidationError("validation", "failed to decode image") ErrImageEncode = errors.NewValidationError("validation", "failed to encode image") )
Image processing errors
var StandardImageSizes = []ImageSize{
{Name: "small", MaxWidth: 400, MaxHeight: 400, Quality: 80},
{Name: "medium", MaxWidth: 800, MaxHeight: 800, Quality: 85},
{Name: "large", MaxWidth: 1920, MaxHeight: 1080, Quality: 90},
}
StandardImageSizes defines the standard sizes for Mastodon compatibility
Functions ¶
func DecodeBlurhash ¶
DecodeBlurhash decodes a blurhash string into an image
func EnsureFilenameHasExtension ¶
EnsureFilenameHasExtension returns a filename with an extension that matches the supplied MIME type. If the filename already contains an extension it is returned as-is. When no extension is present, the helper attempts to infer one using mime.ExtensionsByType with a fallback map that covers the formats accepted by the media service.
func GenerateBlurhash ¶
GenerateBlurhash generates a blurhash for the given image componentX and componentY control the level of detail (typically 4x3 or 4x4)
func GenerateBlurhashFromBytes ¶
GenerateBlurhashFromBytes generates a blurhash from image bytes
func GetDefaultBlurhash ¶
func GetDefaultBlurhash() string
GetDefaultBlurhash returns a default blurhash for error cases
func IsAudioCodecExported ¶
IsAudioCodecExported is an exported version of isAudioCodec for testing/demo purposes
func IsVideoCodecExported ¶
IsVideoCodecExported is an exported version of isVideoCodec for testing/demo purposes
func ProcessImage ¶
func ProcessImage(data []byte, mimeType string) (map[string]*ProcessedImage, error)
ProcessImage processes an image to multiple sizes and generates blurhash
Types ¶
type BandwidthAnalytics ¶
type BandwidthAnalytics interface {
ProcessLogFiles(ctx context.Context, bucket, prefix string) error
GetBandwidthReport(ctx context.Context, period string, start, end time.Time) (*BandwidthReport, error)
GetCostBreakdown(ctx context.Context, start, end time.Time) (*CostBreakdown, error)
TrackBandwidthUsage(ctx context.Context, usage *BandwidthUsage) error
}
BandwidthAnalytics handles bandwidth usage analytics
func NewBandwidthAnalytics ¶
func NewBandwidthAnalytics(ctx context.Context, storageService interface { StoreBandwidthUsage(ctx context.Context, usage *BandwidthUsage) error GetBandwidthUsage(ctx context.Context, start, end time.Time) ([]*BandwidthUsage, error) }) (BandwidthAnalytics, error)
NewBandwidthAnalytics creates a new bandwidth analytics service
type BandwidthReport ¶
type BandwidthReport struct {
Period string `json:"period"`
StartTime time.Time `json:"start_time"`
EndTime time.Time `json:"end_time"`
TotalBytes int64 `json:"total_bytes"`
TotalCost float64 `json:"total_cost"`
ByMedia map[string]MediaUsage `json:"by_media"`
ByQuality map[string]int64 `json:"by_quality"`
ByRegion map[string]RegionUsage `json:"by_region"`
ByUser map[string]int64 `json:"by_user"`
TopMedia []MediaUsage `json:"top_media"`
Trends []DataPoint `json:"trends"`
GeneratedAt time.Time `json:"generated_at"`
}
BandwidthReport contains bandwidth analytics
type BandwidthUsage ¶
type BandwidthUsage struct {
MediaID string `json:"media_id"`
UserID string `json:"user_id"`
Bytes int64 `json:"bytes"`
Quality string `json:"quality"`
Region string `json:"region"`
Timestamp time.Time `json:"timestamp"`
UserAgent string `json:"user_agent"`
Referrer string `json:"referrer"`
}
BandwidthUsage represents real-time bandwidth usage
type CloudFrontLogEntry ¶
type CloudFrontLogEntry struct {
Date string
Time string
EdgeLocation string
Bytes int64
ClientIP string
Method string
Host string
URI string
Status int
Referrer string
UserAgent string
QueryString string
}
CloudFrontLogEntry represents a parsed CloudFront log entry
type CloudWatchEnhancedStreamingService ¶
type CloudWatchEnhancedStreamingService struct {
// contains filtered or unexported fields
}
CloudWatchEnhancedStreamingService provides real CloudWatch data for streaming optimization
func NewCloudWatchEnhancedStreamingService ¶
func NewCloudWatchEnhancedStreamingService(awsConfig aws.Config, repo streamingCloudWatchRepo, logger *zap.Logger) *CloudWatchEnhancedStreamingService
NewCloudWatchEnhancedStreamingService creates a new CloudWatch enhanced streaming service
func (*CloudWatchEnhancedStreamingService) GetOptimalQuality ¶
func (s *CloudWatchEnhancedStreamingService) GetOptimalQuality(ctx context.Context, mediaID, userRegion string) (string, error)
GetOptimalQuality determines the best quality based on real CloudWatch performance data
func (*CloudWatchEnhancedStreamingService) GetRealConcurrentMetrics ¶
func (s *CloudWatchEnhancedStreamingService) GetRealConcurrentMetrics(ctx context.Context, mediaID string, totalViews int64) (int64, error)
GetRealConcurrentMetrics retrieves real concurrent viewer metrics from CloudWatch with DynamORM caching
func (*CloudWatchEnhancedStreamingService) GetRealGeographicData ¶
func (s *CloudWatchEnhancedStreamingService) GetRealGeographicData(ctx context.Context, mediaID string, totalViews int64) (map[string]int64, error)
GetRealGeographicData retrieves real geographic distribution from CloudWatch with DynamORM caching
func (*CloudWatchEnhancedStreamingService) GetRealQualityBreakdown ¶
func (s *CloudWatchEnhancedStreamingService) GetRealQualityBreakdown(ctx context.Context, mediaID string, totalViews int64) (map[string]int64, error)
GetRealQualityBreakdown retrieves real quality breakdown from CloudWatch with DynamORM caching
type CostBreakdown ¶
type CostBreakdown struct {
StartTime time.Time `json:"start_time"`
EndTime time.Time `json:"end_time"`
TotalCost float64 `json:"total_cost"`
BandwidthCost float64 `json:"bandwidth_cost"`
RequestCost float64 `json:"request_cost"`
StorageCost float64 `json:"storage_cost"`
ByService map[string]float64 `json:"by_service"`
ByMedia map[string]float64 `json:"by_media"`
ByUser map[string]UserCost `json:"by_user"`
Recommendations []CostRecommendation `json:"recommendations"`
Projections CostProjection `json:"projections"`
}
CostBreakdown provides detailed cost analysis
type CostProjection ¶
type CostProjection struct {
Monthly float64 `json:"monthly"`
Yearly float64 `json:"yearly"`
PerUser float64 `json:"per_user"`
Trending string `json:"trending"` // up, down, stable
}
CostProjection provides cost forecasting
type CostRecommendation ¶
type CostRecommendation struct {
Type string `json:"type"`
Description string `json:"description"`
Savings float64 `json:"potential_savings"`
Priority string `json:"priority"`
}
CostRecommendation suggests cost optimization
type DASHManifest ¶
type DASHManifest struct {
MediaID string `json:"media_id"`
ManifestURL string `json:"manifest_url"`
VideoTracks []DASHTrack `json:"video_tracks"`
AudioTracks []DASHTrack `json:"audio_tracks"`
Duration float64 `json:"duration"`
CreatedAt time.Time `json:"created_at"`
}
DASHManifest represents DASH streaming manifest
type DASHTrack ¶
type DASHTrack struct {
ID string `json:"id"`
Type string `json:"type"` // video, audio
Quality string `json:"quality"`
Bandwidth int `json:"bandwidth"`
Resolution string `json:"resolution,omitempty"`
Codecs string `json:"codecs"`
URL string `json:"url"`
}
DASHTrack represents a track in DASH
type DataPoint ¶
type DataPoint struct {
Timestamp time.Time `json:"timestamp"`
Value float64 `json:"value"`
Label string `json:"label"`
}
DataPoint represents a time-series data point
type HLSManifest ¶
type HLSManifest struct {
MediaID string `json:"media_id"`
MasterURL string `json:"master_url"`
Variants []HLSVariant `json:"variants"`
Duration float64 `json:"duration"`
CreatedAt time.Time `json:"created_at"`
}
HLSManifest represents HLS streaming manifest
type HLSVariant ¶
type HLSVariant struct {
Quality string `json:"quality"`
Bandwidth int `json:"bandwidth"`
Resolution string `json:"resolution"`
Codecs string `json:"codecs"`
URL string `json:"url"`
}
HLSVariant represents a quality variant in HLS
type ImageSize ¶
type ImageSize struct {
Name string
MaxWidth int
MaxHeight int
Quality int // JPEG quality (1-100)
}
ImageSize represents a target image size
type MediaUsage ¶
type MediaUsage struct {
MediaID string `json:"media_id"`
Bytes int64 `json:"bytes"`
Requests int64 `json:"requests"`
UniqueUsers int64 `json:"unique_users"`
Cost float64 `json:"cost"`
AvgBitrate float64 `json:"avg_bitrate"`
}
MediaUsage represents bandwidth usage for a specific media item
type ProcessedImage ¶
ProcessedImage contains the result of processing an image
type RegionUsage ¶
type RegionUsage struct {
Region string `json:"region"`
Bytes int64 `json:"bytes"`
Requests int64 `json:"requests"`
Cost float64 `json:"cost"`
}
RegionUsage represents bandwidth usage by region
type StreamingAnalytics ¶
type StreamingAnalytics struct {
MediaID string `json:"media_id"`
ViewCount int64 `json:"view_count"`
BandwidthUsed int64 `json:"bandwidth_used"` // bytes
QualityBreakdown map[string]int64 `json:"quality_breakdown"`
GeographicData map[string]int64 `json:"geographic_data"`
BufferingEvents int64 `json:"buffering_events"`
AverageWatchTime float64 `json:"average_watch_time"` // seconds
PeakConcurrent int64 `json:"peak_concurrent"`
LastUpdated time.Time `json:"last_updated"`
}
StreamingAnalytics contains analytics for a media item
type StreamingEvent ¶
type StreamingEvent struct {
MediaID string `json:"media_id"`
UserID string `json:"user_id,omitempty"`
EventType string `json:"event_type"` // play, pause, buffer, quality_change, error
Quality string `json:"quality"`
Timestamp time.Time `json:"timestamp"`
Duration float64 `json:"duration,omitempty"` // seconds
BytesLoaded int64 `json:"bytes_loaded,omitempty"`
Country string `json:"country,omitempty"`
UserAgent string `json:"user_agent,omitempty"`
}
StreamingEvent represents a streaming event for analytics
type StreamingService ¶
type StreamingService interface {
GenerateStreamingURL(mediaID string, quality string) (*StreamingURL, error)
GetStreamingAnalytics(mediaID string) (*StreamingAnalytics, error)
RecordStreamingEvent(ctx context.Context, event *StreamingEvent) error
GenerateHLSManifest(mediaID string) (*HLSManifest, error)
GenerateDASHManifest(mediaID string) (*DASHManifest, error)
}
StreamingService handles media streaming operations
func NewStreamingService ¶
func NewStreamingService(ctx context.Context, distributionDomain, keyPairID string, privateKey []byte, mediaStorage streaming.MediaStorage) (StreamingService, error)
NewStreamingService creates a new streaming service
func NewStreamingServiceWithStorage ¶
func NewStreamingServiceWithStorage(ctx context.Context, distributionDomain, keyPairID string, privateKey []byte, mediaStorage streaming.MediaStorage, storage core.RepositoryStorage) (StreamingService, error)
NewStreamingServiceWithStorage creates a new streaming service with CloudWatch enhancement
type StreamingURL ¶
type StreamingURL struct {
URL string `json:"url"`
ExpiresAt time.Time `json:"expires_at"`
Quality string `json:"quality"`
Protocol string `json:"protocol"` // HLS, DASH, Progressive
}
StreamingURL represents a signed streaming URL
type UserCost ¶
type UserCost struct {
UserID string `json:"user_id"`
TotalCost float64 `json:"total_cost"`
Bandwidth int64 `json:"bandwidth"`
Requests int64 `json:"requests"`
MediaItems int `json:"media_items"`
}
UserCost represents cost attribution to a user
type VideoMetadata ¶
type VideoMetadata struct {
Width int `json:"width"`
Height int `json:"height"`
Duration int `json:"duration"` // Duration in milliseconds
DurationSeconds float64 `json:"duration_seconds"` // Duration in seconds (more precise)
Timescale uint32 `json:"timescale"` // Movie timescale from mvhd
CreationTime uint32 `json:"creation_time"` // Creation time from mvhd
ModificationTime uint32 `json:"modification_time"` // Modification time from mvhd
VideoCodec string `json:"video_codec"` // Video codec identifier
AudioCodec string `json:"audio_codec"` // Audio codec identifier
HasAudio bool `json:"has_audio"` // Whether the file contains audio
HasVideo bool `json:"has_video"` // Whether the file contains video
Bitrate int64 `json:"bitrate"` // Estimated bitrate in bits per second
FrameRate float64 `json:"frame_rate"` // Estimated frame rate
FileSize int64 `json:"file_size"` // File size in bytes
}
VideoMetadata contains extracted video metadata from MP4/MOV files
func ParseVideoMetadata ¶
func ParseVideoMetadata(data []byte) (*VideoMetadata, error)
ParseVideoMetadata extracts metadata from MP4/MOV video data
type VideoMetadataParser ¶
type VideoMetadataParser struct {
// contains filtered or unexported fields
}
VideoMetadataParser handles parsing of MP4/MOV video metadata
func NewVideoMetadataParser ¶
func NewVideoMetadataParser(data []byte) *VideoMetadataParser
NewVideoMetadataParser creates a new parser for the given video data