mirror of
https://github.com/photoprism/photoprism.git
synced 2026-01-23 02:24:24 +00:00
Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
parent
933cc5031f
commit
06e59d9993
12 changed files with 94 additions and 99 deletions
|
|
@ -1,7 +1,6 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
|
@ -113,7 +112,7 @@ func GetVideo(router *gin.RouterGroup) {
|
|||
} else if c.Request.Header.Get("Range") == "" && info.VideoCodec == format.Codec {
|
||||
defer reader.Close()
|
||||
AddVideoCacheHeader(c, conf.CdnVideo())
|
||||
c.DataFromReader(http.StatusOK, info.VideoSize(), clean.ContentType(info.VideoContentType()), reader, nil)
|
||||
c.DataFromReader(http.StatusOK, info.VideoSize(), info.VideoContentType(), reader, nil)
|
||||
return
|
||||
} else if cacheName, cacheErr := fs.CacheFileFromReader(filepath.Join(conf.MediaFileCachePath(f.FileHash), f.FileHash+info.VideoFileExt()), reader); cacheErr != nil {
|
||||
log.Errorf("video: failed to cache %s embedded in %s (%s)", strings.ToUpper(videoFileType), clean.Log(f.FileName), cacheErr)
|
||||
|
|
@ -164,7 +163,7 @@ func GetVideo(router *gin.RouterGroup) {
|
|||
} else {
|
||||
if videoCodec != "" && videoCodec != videoFileType {
|
||||
log.Debugf("video: %s is %s encoded and requires no transcoding, average bitrate %.1f MBit/s", clean.Log(f.FileName), strings.ToUpper(videoCodec), videoBitrate)
|
||||
AddContentTypeHeader(c, clean.ContentType(fmt.Sprintf("%s; codecs=\"%s\"", f.FileMime, clean.Codec(videoCodec))))
|
||||
AddContentTypeHeader(c, video.ContentType(mediaFile.MimeType(), videoFileType, videoCodec))
|
||||
} else {
|
||||
log.Debugf("video: %s is streamed directly, average bitrate %.1f MBit/s", clean.Log(f.FileName), videoBitrate)
|
||||
AddContentTypeHeader(c, f.ContentType())
|
||||
|
|
|
|||
|
|
@ -10,13 +10,14 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
"github.com/photoprism/photoprism/pkg/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/video"
|
||||
)
|
||||
|
||||
func TestGetVideo(t *testing.T) {
|
||||
t.Run("ContentTypeAVC", func(t *testing.T) {
|
||||
assert.Equal(t, header.ContentTypeAVC, clean.ContentType("video/mp4; codecs=\"avc1\""))
|
||||
mimeType := fmt.Sprintf("video/mp4; codecs=\"%s\"", clean.Codec("avc1"))
|
||||
assert.Equal(t, header.ContentTypeAVC, clean.ContentType(mimeType))
|
||||
assert.Equal(t, header.ContentTypeAVC, video.ContentType(mimeType, "mp4", "avc1"))
|
||||
})
|
||||
|
||||
t.Run("NoHash", func(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -6,14 +6,9 @@ import (
|
|||
"math"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/media/video"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/header"
|
||||
|
||||
"github.com/dustin/go-humanize/english"
|
||||
"github.com/gosimple/slug"
|
||||
"github.com/jinzhu/gorm"
|
||||
|
|
@ -26,6 +21,7 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/media"
|
||||
"github.com/photoprism/photoprism/pkg/media/colors"
|
||||
"github.com/photoprism/photoprism/pkg/media/projection"
|
||||
"github.com/photoprism/photoprism/pkg/media/video"
|
||||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
|
@ -888,51 +884,12 @@ func (m *File) SetOrientation(val int, src string) *File {
|
|||
|
||||
// ContentType returns the HTTP content type of the file including the codec as a parameter, if known.
|
||||
func (m *File) ContentType() (contentType string) {
|
||||
contentType = m.FileMime
|
||||
|
||||
if m.FileVideo {
|
||||
if contentType == "" {
|
||||
var codec string
|
||||
|
||||
if m.FileCodec != "" {
|
||||
codec = m.FileCodec
|
||||
} else {
|
||||
codec = m.FileType
|
||||
}
|
||||
|
||||
switch codec {
|
||||
case video.CodecAVC, "mov", "mp4", "avc", "v_avc", "v_avc1":
|
||||
contentType = header.ContentTypeAVC // Advanced Video Coding (AVC), also known as H.264
|
||||
case video.CodecHEVC, "hvc", "hevc", "v_hvc", "v_hvc1":
|
||||
contentType = header.ContentTypeHEVC // High Efficiency Video Coding (HEVC), also known as H.265
|
||||
case video.CodecHEV1, "hev":
|
||||
contentType = header.ContentTypeHEV1 // High Efficiency Video Coding (HEVC) Bitstream
|
||||
case video.CodecVVC, "vvc":
|
||||
contentType = header.ContentTypeVVC // Versatile Video Coding (VVC), also known as H.266
|
||||
case video.CodecEVC, "evc":
|
||||
contentType = header.ContentTypeEVC // MPEG-5 Essential Video Coding (EVC), also known as ISO/IEC 23094-1
|
||||
case video.CodecVP8, "vp08":
|
||||
contentType = header.ContentTypeVP8
|
||||
case video.CodecVP9, "vp9":
|
||||
contentType = header.ContentTypeVP9
|
||||
case video.CodecAV1, "av1":
|
||||
contentType = header.ContentTypeAV1
|
||||
case video.CodecOGV, "ogg":
|
||||
contentType = header.ContentTypeOGV
|
||||
case "webm":
|
||||
contentType = header.ContentTypeWebM
|
||||
}
|
||||
}
|
||||
|
||||
if contentType != "" && !strings.Contains(contentType, ";") {
|
||||
if codec := clean.Codec(m.FileCodec); codec != "" {
|
||||
contentType = fmt.Sprintf("%s; codecs=\"%s\"", contentType, codec)
|
||||
}
|
||||
}
|
||||
contentType = video.ContentType(m.FileMime, m.FileType, m.FileCodec)
|
||||
} else {
|
||||
contentType = clean.ContentType(m.FileMime)
|
||||
}
|
||||
|
||||
contentType = clean.ContentType(contentType)
|
||||
|
||||
log.Debugf("file: %s has content type %s", clean.Log(m.FileName), clean.LogQuote(contentType))
|
||||
|
||||
return contentType
|
||||
|
|
|
|||
|
|
@ -4,14 +4,14 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
|
||||
"github.com/gosimple/slug"
|
||||
"github.com/jinzhu/gorm"
|
||||
"github.com/ulule/deepcopier"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/entity"
|
||||
"github.com/photoprism/photoprism/internal/event"
|
||||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
"github.com/photoprism/photoprism/pkg/media/video"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
||||
|
|
@ -200,7 +200,7 @@ func (m *Photo) MediaInfo() (mediaHash, mediaCodec, mediaMime string) {
|
|||
if m.PhotoType == entity.MediaVideo || m.PhotoType == entity.MediaLive {
|
||||
for _, f := range m.Files {
|
||||
if f.FileVideo && f.FileHash != "" {
|
||||
return f.FileHash, f.FileCodec, clean.ContentType(f.FileMime)
|
||||
return f.FileHash, f.FileCodec, video.ContentType(f.FileMime, f.FileType, f.FileCodec)
|
||||
}
|
||||
}
|
||||
} else if m.PhotoType == entity.MediaVector {
|
||||
|
|
|
|||
|
|
@ -550,16 +550,13 @@ func (m *MediaFile) ContentType() string {
|
|||
|
||||
m.contentType = m.MimeType()
|
||||
|
||||
// Append codecs if media file is a video.
|
||||
// Generate normalized HTTP content type.
|
||||
if m.IsVideo() {
|
||||
if !strings.Contains(m.contentType, ";") && m.MetaData().Codec != "" {
|
||||
m.contentType = fmt.Sprintf("%s; codecs=\"%s\"", m.contentType, clean.Codec(m.MetaData().Codec))
|
||||
}
|
||||
m.contentType = video.ContentType(m.contentType, m.FileType().String(), m.MetaData().Codec)
|
||||
} else {
|
||||
m.contentType = clean.ContentType(m.contentType)
|
||||
}
|
||||
|
||||
// Normalize media content type.
|
||||
m.contentType = clean.ContentType(m.contentType)
|
||||
|
||||
log.Debugf("media: %s has content type %s", clean.Log(m.RootRelName()), clean.LogQuote(m.contentType))
|
||||
|
||||
return m.contentType
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ func ContentType(s string) string {
|
|||
s = Type(s)
|
||||
|
||||
// Replace "video/quicktime" with "video/mp4" as the container formats are largely compatible.
|
||||
s = strings.Replace(s, "video/quicktime", "video/mp4", 1)
|
||||
s = strings.Replace(s, header.ContentTypeQT, header.ContentTypeMP4, 1)
|
||||
|
||||
switch s {
|
||||
case "":
|
||||
|
|
|
|||
|
|
@ -34,12 +34,14 @@ const (
|
|||
ContentTypePNG = "image/png"
|
||||
ContentTypeJPEG = "image/jpeg"
|
||||
ContentTypeSVG = "image/svg+xml"
|
||||
ContentTypeAVC32 = "video/mp4; codecs=\"avc1.640020\"" // MPEG-4 AVC, High Profile Level 3.2
|
||||
ContentTypeAVC = "video/mp4; codecs=\"avc1.640028\"" // MPEG-4 AVC, High Profile Level 4.0
|
||||
ContentTypeHEVC = "video/mp4; codecs=\"hvc1.2.4.L120.B0\"" // HEVC MP4 Main10 Profile, Main Tier, Level 4.0
|
||||
ContentTypeHEV1 = "video/mp4; codecs=\"hev1.2.4.L120.B0\"" // HEVC Bitstream, not supported on macOS
|
||||
ContentTypeVVC = "video/mp4; codecs=\"vvc1\"" // Versatile Video Coding (VVC), also known as H.266
|
||||
ContentTypeEVC = "video/mp4; codecs=\"evc1\"" // MPEG-5 Essential Video Coding (EVC), also known as ISO/IEC 23094-1
|
||||
ContentTypeQT = "video/quicktime"
|
||||
ContentTypeMP4 = "video/mp4"
|
||||
ContentTypeAVC32 = ContentTypeMP4 + "; codecs=\"avc1.640020\"" // MPEG-4 AVC, High Profile Level 3.2
|
||||
ContentTypeAVC = ContentTypeMP4 + "; codecs=\"avc1.640028\"" // MPEG-4 AVC, High Profile Level 4.0
|
||||
ContentTypeHEVC = ContentTypeMP4 + "; codecs=\"hvc1.2.4.L120.B0\"" // HEVC MP4 Main10 Profile, Main Tier, Level 4.0
|
||||
ContentTypeHEV1 = ContentTypeMP4 + "; codecs=\"hev1.2.4.L120.B0\"" // HEVC Bitstream, not supported on macOS
|
||||
ContentTypeVVC = ContentTypeMP4 + "; codecs=\"vvc1\"" // Versatile Video Coding (VVC), also known as H.266
|
||||
ContentTypeEVC = ContentTypeMP4 + "; codecs=\"evc1\"" // MPEG-5 Essential Video Coding (EVC), also known as ISO/IEC 23094-1
|
||||
ContentTypeOGV = "video/ogg"
|
||||
ContentTypeWebM = "video/webm"
|
||||
ContentTypeVP8 = "video/webm; codecs=\"vp8\""
|
||||
|
|
|
|||
|
|
@ -2,24 +2,59 @@ package video
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
"github.com/photoprism/photoprism/pkg/header"
|
||||
)
|
||||
|
||||
// Standard content types.
|
||||
const (
|
||||
ContentTypeDefault = "application/octet-stream"
|
||||
ContentTypeAVC = fs.MimeTypeMP4 + `; codecs="avc1"`
|
||||
ContentTypeMOV = fs.MimeTypeMOV
|
||||
)
|
||||
|
||||
// ContentType composes the video content type from the given mime type and codec.
|
||||
func ContentType(mimeType string, codec Codec) string {
|
||||
if codec == CodecUnknown {
|
||||
return mimeType
|
||||
} else if mimeType == "" {
|
||||
return ContentTypeDefault
|
||||
// ContentType returns a normalized video content type strings based on the video file type and codec.
|
||||
func ContentType(mediaType, fileType, videoCodec string) string {
|
||||
if mediaType == "" && fileType == "" && videoCodec == "" {
|
||||
return header.ContentTypeBinary
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s; codecs=\"%s\"", mimeType, codec)
|
||||
if mediaType == "" {
|
||||
var c string
|
||||
|
||||
if videoCodec != "" {
|
||||
c = Codecs[videoCodec]
|
||||
} else {
|
||||
c = fileType
|
||||
}
|
||||
|
||||
switch c {
|
||||
case "mov", "mp4":
|
||||
mediaType = header.ContentTypeMP4
|
||||
case CodecAVC, "avc":
|
||||
mediaType = header.ContentTypeAVC // Advanced Video Coding (AVC), also known as H.264
|
||||
case CodecHEVC, "hvc", "hevc":
|
||||
mediaType = header.ContentTypeHEVC // High Efficiency Video Coding (HEVC), also known as H.265
|
||||
case CodecHEV1, "hev":
|
||||
mediaType = header.ContentTypeHEV1 // High Efficiency Video Coding (HEVC) Bitstream
|
||||
case CodecVVC, "vvc":
|
||||
mediaType = header.ContentTypeVVC // Versatile Video Coding (VVC), also known as H.266
|
||||
case CodecEVC, "evc":
|
||||
mediaType = header.ContentTypeEVC // MPEG-5 Essential Video Coding (EVC), also known as ISO/IEC 23094-1
|
||||
case CodecVP8, "vp08":
|
||||
mediaType = header.ContentTypeVP8
|
||||
case CodecVP9, "vp9":
|
||||
mediaType = header.ContentTypeVP9
|
||||
case CodecAV1, "av1":
|
||||
mediaType = header.ContentTypeAV1
|
||||
case CodecOGV, "ogg":
|
||||
mediaType = header.ContentTypeOGV
|
||||
case CodecWebM:
|
||||
mediaType = header.ContentTypeWebM
|
||||
}
|
||||
}
|
||||
|
||||
// Add codec parameter, if possible.
|
||||
if mediaType != "" && !strings.Contains(mediaType, ";") {
|
||||
if codec, found := Codecs[videoCodec]; found && codec != "" {
|
||||
mediaType = fmt.Sprintf("%s; codecs=\"%s\"", mediaType, codec)
|
||||
}
|
||||
}
|
||||
|
||||
return clean.ContentType(mediaType)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,22 +6,23 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/photoprism/photoprism/pkg/header"
|
||||
)
|
||||
|
||||
func TestContentType(t *testing.T) {
|
||||
t.Run("QuickTime", func(t *testing.T) {
|
||||
assert.Equal(t, fs.MimeTypeMOV, ContentType(fs.MimeTypeMOV, ""))
|
||||
assert.Equal(t, fs.MimeTypeMP4, ContentType(fs.MimeTypeMOV, "", ""))
|
||||
})
|
||||
t.Run("QuickTime_HVC", func(t *testing.T) {
|
||||
assert.Equal(t, `video/quicktime; codecs="hvc1"`, ContentType(fs.MimeTypeMOV, CodecHEVC))
|
||||
assert.Equal(t, header.ContentTypeHEVC, ContentType(fs.MimeTypeMOV, "mov", CodecHEVC))
|
||||
})
|
||||
t.Run("MP4", func(t *testing.T) {
|
||||
assert.Equal(t, fs.MimeTypeMP4, ContentType(fs.MimeTypeMP4, ""))
|
||||
assert.Equal(t, fs.MimeTypeMP4, ContentType(fs.MimeTypeMP4, "", ""))
|
||||
})
|
||||
t.Run("MP4_AVC", func(t *testing.T) {
|
||||
assert.Equal(t, ContentTypeAVC, ContentType(fs.MimeTypeMP4, CodecAVC))
|
||||
assert.Equal(t, header.ContentTypeAVC, ContentType(fs.MimeTypeMP4, "", CodecAVC))
|
||||
})
|
||||
t.Run("MP4_HVC", func(t *testing.T) {
|
||||
assert.Equal(t, `video/mp4; codecs="hvc1"`, ContentType(fs.MimeTypeMP4, CodecHEVC))
|
||||
assert.Equal(t, header.ContentTypeHEVC, ContentType(fs.MimeTypeMP4, "", CodecHEVC))
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/photoprism/photoprism/pkg/header"
|
||||
"github.com/photoprism/photoprism/pkg/media"
|
||||
)
|
||||
|
||||
|
|
@ -69,10 +70,10 @@ func (info Info) VideoBitrate() float64 {
|
|||
// VideoContentType composes the video content type from its mime type and codec.
|
||||
func (info Info) VideoContentType() string {
|
||||
if info.VideoMimeType == "" {
|
||||
return ContentTypeDefault
|
||||
return header.ContentTypeBinary
|
||||
}
|
||||
|
||||
return ContentType(info.VideoMimeType, info.VideoCodec)
|
||||
return ContentType(info.VideoMimeType, info.FileType.String(), info.VideoCodec)
|
||||
}
|
||||
|
||||
// VideoFileExt returns the appropriate video file extension based on the mime type and defaults to fs.ExtMP4 otherwise.
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/photoprism/photoprism/pkg/header"
|
||||
)
|
||||
|
||||
func TestInfo(t *testing.T) {
|
||||
|
|
@ -27,7 +28,7 @@ func TestInfo(t *testing.T) {
|
|||
info := NewInfo()
|
||||
info.VideoMimeType = fs.MimeTypeMP4
|
||||
info.VideoCodec = CodecAVC
|
||||
assert.Equal(t, ContentTypeAVC, info.VideoContentType())
|
||||
assert.Equal(t, header.ContentTypeAVC, info.VideoContentType())
|
||||
})
|
||||
t.Run("VideoFileExt", func(t *testing.T) {
|
||||
info := NewInfo()
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/photoprism/photoprism/pkg/header"
|
||||
"github.com/photoprism/photoprism/pkg/media"
|
||||
)
|
||||
|
||||
|
|
@ -39,7 +40,7 @@ func TestProbeFile(t *testing.T) {
|
|||
assert.Equal(t, media.Video, info.MediaType)
|
||||
assert.Equal(t, CodecAVC, info.VideoCodec)
|
||||
assert.Equal(t, fs.MimeTypeMP4, info.VideoMimeType)
|
||||
assert.Equal(t, ContentTypeAVC, info.VideoContentType())
|
||||
assert.Equal(t, header.ContentTypeAVC, info.VideoContentType())
|
||||
assert.Equal(t, "810.0081ms", info.Duration.String())
|
||||
assert.InEpsilon(t, 0.81, info.Duration.Seconds(), 0.01)
|
||||
assert.Equal(t, 1, info.Tracks)
|
||||
|
|
@ -66,7 +67,7 @@ func TestProbeFile(t *testing.T) {
|
|||
assert.Equal(t, media.Video, info.MediaType)
|
||||
assert.Equal(t, CodecAVC, info.VideoCodec)
|
||||
assert.Equal(t, fs.MimeTypeMP4, info.VideoMimeType)
|
||||
assert.Equal(t, ContentTypeAVC, info.VideoContentType())
|
||||
assert.Equal(t, header.ContentTypeAVC, info.VideoContentType())
|
||||
assert.Equal(t, "1.066666666s", info.Duration.String())
|
||||
assert.InEpsilon(t, 1.066, info.Duration.Seconds(), 0.01)
|
||||
assert.Equal(t, 2, info.Tracks)
|
||||
|
|
@ -93,7 +94,7 @@ func TestProbeFile(t *testing.T) {
|
|||
assert.Equal(t, media.Video, info.MediaType)
|
||||
assert.Equal(t, CodecHEVC, info.VideoCodec)
|
||||
assert.Equal(t, fs.MimeTypeMOV, info.VideoMimeType)
|
||||
assert.Equal(t, ContentTypeMOV+`; codecs="hvc1"`, info.VideoContentType())
|
||||
assert.Equal(t, header.ContentTypeHEVC, info.VideoContentType())
|
||||
assert.Equal(t, "1.166666666s", info.Duration.String())
|
||||
assert.InEpsilon(t, 1.166, info.Duration.Seconds(), 0.01)
|
||||
assert.Equal(t, 5, info.Tracks)
|
||||
|
|
@ -119,7 +120,7 @@ func TestProbeFile(t *testing.T) {
|
|||
assert.Equal(t, int64(-1), info.ThumbOffset)
|
||||
assert.Equal(t, media.Video, info.MediaType)
|
||||
assert.Equal(t, CodecUnknown, info.VideoCodec)
|
||||
assert.Equal(t, ContentTypeDefault, info.VideoContentType())
|
||||
assert.Equal(t, header.ContentTypeBinary, info.VideoContentType())
|
||||
assert.Equal(t, "", info.VideoMimeType)
|
||||
assert.Equal(t, "0s", info.Duration.String())
|
||||
assert.Equal(t, 0, info.Tracks)
|
||||
|
|
@ -146,7 +147,7 @@ func TestProbeFile(t *testing.T) {
|
|||
assert.Equal(t, media.Live, info.MediaType)
|
||||
assert.Equal(t, CodecAVC, info.VideoCodec)
|
||||
assert.Equal(t, fs.MimeTypeMP4, info.VideoMimeType)
|
||||
assert.Equal(t, ContentTypeAVC, info.VideoContentType())
|
||||
assert.Equal(t, header.ContentTypeAVC, info.VideoContentType())
|
||||
assert.Equal(t, "1.024s", info.Duration.String())
|
||||
assert.InEpsilon(t, 1.024, info.Duration.Seconds(), 0.01)
|
||||
assert.Equal(t, 2, info.Tracks)
|
||||
|
|
@ -179,7 +180,7 @@ func TestProbe(t *testing.T) {
|
|||
assert.Equal(t, media.Video, info.MediaType)
|
||||
assert.Equal(t, CodecAVC, info.VideoCodec)
|
||||
assert.Equal(t, fs.MimeTypeMP4, info.VideoMimeType)
|
||||
assert.Equal(t, ContentTypeAVC, info.VideoContentType())
|
||||
assert.Equal(t, header.ContentTypeAVC, info.VideoContentType())
|
||||
assert.Equal(t, "810.0081ms", info.Duration.String())
|
||||
assert.InEpsilon(t, 0.81, info.Duration.Seconds(), 0.01)
|
||||
assert.Equal(t, 1, info.Tracks)
|
||||
|
|
@ -209,7 +210,7 @@ func TestProbe(t *testing.T) {
|
|||
assert.Equal(t, media.Video, info.MediaType)
|
||||
assert.Equal(t, CodecAVC, info.VideoCodec)
|
||||
assert.Equal(t, fs.MimeTypeMP4, info.VideoMimeType)
|
||||
assert.Equal(t, ContentTypeAVC, info.VideoContentType())
|
||||
assert.Equal(t, header.ContentTypeAVC, info.VideoContentType())
|
||||
assert.Equal(t, "1.024s", info.Duration.String())
|
||||
assert.InEpsilon(t, 1.024, info.Duration.Seconds(), 0.01)
|
||||
assert.Equal(t, 2, info.Tracks)
|
||||
|
|
@ -239,7 +240,7 @@ func TestProbe(t *testing.T) {
|
|||
assert.Equal(t, media.Live, info.MediaType)
|
||||
assert.Equal(t, CodecAVC, info.VideoCodec)
|
||||
assert.Equal(t, fs.MimeTypeMP4, info.VideoMimeType)
|
||||
assert.Equal(t, ContentTypeAVC, info.VideoContentType())
|
||||
assert.Equal(t, header.ContentTypeAVC, info.VideoContentType())
|
||||
assert.Equal(t, "1.024s", info.Duration.String())
|
||||
assert.InEpsilon(t, 1.024, info.Duration.Seconds(), 0.01)
|
||||
assert.Equal(t, 2, info.Tracks)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue