Files
ffmpeg-go-rtmp/utils.go
xingnaidong1 a538f53f13 demo save
2022-01-06 17:28:07 +08:00

223 lines
4.1 KiB
Go

package ffmpeg_go
import (
"fmt"
"hash/fnv"
"sort"
"strconv"
"strings"
"github.com/u2takey/go-utils/sets"
)
func getString(item interface{}) string {
if a, ok := item.(interface{ String() string }); ok {
return a.String()
}
switch a := item.(type) {
case string:
return a
case []string:
return strings.Join(a, ", ")
case Args:
return strings.Join(a, ", ")
case []interface{}:
var r []string
for _, b := range a {
r = append(r, getString(b))
}
return strings.Join(r, ", ")
case KwArgs:
var keys, r []string
for k := range a {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
r = append(r, fmt.Sprintf("%s: %s", k, getString(a[k])))
}
return fmt.Sprintf("{%s}", strings.Join(r, ", "))
case map[string]interface{}:
var keys, r []string
for k := range a {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
r = append(r, fmt.Sprintf("%s: %s", k, getString(a[k])))
}
return fmt.Sprintf("{%s}", strings.Join(r, ", "))
}
return fmt.Sprintf("%v", item)
}
func getHash(item interface{}) int {
h := fnv.New64()
switch a := item.(type) {
case interface{ Hash() int }:
return a.Hash()
case string:
_, _ = h.Write([]byte(a))
return int(h.Sum64())
case []byte:
_, _ = h.Write(a)
return int(h.Sum64())
case map[string]interface{}:
b := 0
for k, v := range a {
b += getHash(k) + getHash(v)
}
return b
case KwArgs:
b := 0
for k, v := range a {
b += getHash(k) + getHash(v)
}
return b
default:
_, _ = h.Write([]byte(getString(item)))
return int(h.Sum64())
}
}
func escapeChars(text, chars string) string {
s := sets.NewString()
for _, a := range chars {
s.Insert(string(a))
}
sl := s.List()
if s.Has("\\") {
s.Delete("\\")
sl = append([]string{"\\"}, s.List()...)
}
for _, ch := range sl {
text = strings.ReplaceAll(text, ch, "\\"+ch)
}
return text
}
type Args []string
func (a Args) Sorted() Args {
sort.Strings(a)
return a
}
func (a Args) EscapeWith(chars string) Args {
out := Args{}
for _, b := range a {
out = append(out, escapeChars(b, chars))
}
return out
}
type KwArgs map[string]interface{}
func MergeKwArgs(args []KwArgs) KwArgs {
a := KwArgs{}
for _, b := range args {
for c := range b {
a[c] = b[c]
}
}
return a
}
func (a KwArgs) EscapeWith(chars string) KwArgs {
out := KwArgs{}
for k, v := range a {
out[escapeChars(k, chars)] = escapeChars(getString(v), chars)
}
return out
}
func (a KwArgs) Copy() KwArgs {
r := KwArgs{}
for k := range a {
r[k] = a[k]
}
return r
}
func (a KwArgs) SortedKeys() []string {
var r []string
for k := range a {
r = append(r, k)
}
sort.Strings(r)
return r
}
func (a KwArgs) GetString(k string) string {
if v, ok := a[k]; ok {
return fmt.Sprintf("%v", v)
}
return ""
}
func (a KwArgs) PopString(k string) string {
if c, ok := a[k]; ok {
defer delete(a, k)
return fmt.Sprintf("%v", c)
}
return ""
}
func (a KwArgs) HasKey(k string) bool {
_, ok := a[k]
return ok
}
func (a KwArgs) GetDefault(k string, defaultV interface{}) interface{} {
if v, ok := a[k]; ok {
return v
}
return defaultV
}
func (a KwArgs) PopDefault(k string, defaultV interface{}) interface{} {
if v, ok := a[k]; ok {
defer delete(a, k)
return v
}
return defaultV
}
func ConvertKwargsToCmdLineArgs(kwargs KwArgs) []string {
var keys, args []string
for k := range kwargs {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
v := kwargs[k]
switch a := v.(type) {
case string:
args = append(args, fmt.Sprintf("-%s", k))
if a != "" {
args = append(args, a)
}
case []string:
for _, r := range a {
args = append(args, fmt.Sprintf("-%s", k))
if r != "" {
args = append(args, r)
}
}
case []int:
for _, r := range a {
args = append(args, fmt.Sprintf("-%s", k))
args = append(args, strconv.Itoa(r))
}
case int:
args = append(args, fmt.Sprintf("-%s", k))
args = append(args, strconv.Itoa(a))
default:
args = append(args, fmt.Sprintf("-%s", k))
args = append(args, fmt.Sprintf("%v", a))
}
}
return args
}