diff --git a/.github/workflows/stream_odysee.yml b/.github/workflows/stream_odysee.yml new file mode 100644 index 000000000..3739cfb58 --- /dev/null +++ b/.github/workflows/stream_odysee.yml @@ -0,0 +1,31 @@ +name: odysee + +on: + push: + paths: + - "extractors/odysee/*.go" + - ".github/workflows/stream_odysee.yml" + pull_request: + paths: + - "extractors/odysee/*.go" + - ".github/workflows/stream_odysee.yml" + schedule: + # run ci weekly + - cron: "0 0 * * 0" + +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + matrix: + go: ["1.22"] + os: [ubuntu-latest] + name: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: ${{ matrix.go }} + + - name: Test + run: go test -timeout 5m -race -coverpkg=./... -coverprofile=coverage.txt github.com/iawia002/lux/extractors/odysee diff --git a/README.md b/README.md index 2a925e750..65b3680b0 100644 --- a/README.md +++ b/README.md @@ -648,6 +648,7 @@ $ lux -j "https://www.bilibili.com/video/av20203945" | 小红书 | | ✓ | | | | | [![xiaohongshu](https://github.com/iawia002/lux/actions/workflows/stream_xiaohongshu.yml/badge.svg)](https://github.com/iawia002/lux/actions/workflows/stream_xiaohongshu.yml/) | | Zing MP3 | | ✓ | | ✓ | | | [![zingmp3](https://github.com/iawia002/lux/actions/workflows/stream_zingmp3.yml/badge.svg)](https://github.com/iawia002/lux/actions/workflows/stream_zingmp3.yml/) | | Bitchute | | ✓ | | | | | [![bitchute](https://github.com/iawia002/lux/actions/workflows/stream_bitchute.yml/badge.svg)](https://github.com/iawia002/lux/actions/workflows/stream_bitchute.yml/) | +| Odysee | | ✓ | | ✓ | | | [![odysee](https://github.com/iawia002/lux/actions/workflows/stream_odysee.yml/badge.svg)](https://github.com/iawia002/lux/actions/workflows/stream_odysee.yml/) | ## Known issues diff --git a/app/register.go b/app/register.go index dcce480b0..2a87b51a0 100644 --- a/app/register.go +++ b/app/register.go @@ -20,6 +20,7 @@ import ( _ "github.com/iawia002/lux/extractors/mgtv" _ "github.com/iawia002/lux/extractors/miaopai" _ "github.com/iawia002/lux/extractors/netease" + _ "github.com/iawia002/lux/extractors/odysee" _ "github.com/iawia002/lux/extractors/pinterest" _ "github.com/iawia002/lux/extractors/pixivision" _ "github.com/iawia002/lux/extractors/pornhub" diff --git a/extractors/odysee/odysee.go b/extractors/odysee/odysee.go new file mode 100644 index 000000000..1c0036fb3 --- /dev/null +++ b/extractors/odysee/odysee.go @@ -0,0 +1,96 @@ +package odysee + +import ( + "compress/flate" + "compress/gzip" + "encoding/json" + "io" + "net/http" + "regexp" + + "github.com/iawia002/lux/extractors" + "github.com/iawia002/lux/request" + "github.com/pkg/errors" +) + +func init() { + extractors.Register("odysee", New()) +} + +type extractor struct{} + +type odyseePayload struct { + ContentURL string `json:"contentUrl"` + Description string `json:"description"` + Name string `json:"name"` + ThumbnailURL string `json:"thumbnailUrl"` + URL string `json:"url"` +} + +// New returns an odysee extractor. +func New() extractors.Extractor { + return &extractor{} +} + +func (e *extractor) Extract(u string, option extractors.Options) ([]*extractors.Data, error) { + res, err := request.Request(http.MethodGet, u, nil, nil) + if err != nil { + return nil, errors.WithStack(err) + } + defer res.Body.Close() // nolint + + var reader io.ReadCloser + switch res.Header.Get("Content-Encoding") { + case "gzip": + reader, _ = gzip.NewReader(res.Body) + case "deflate": + reader = flate.NewReader(res.Body) + default: + reader = res.Body + } + defer reader.Close() // nolint + + b, err := io.ReadAll(reader) + if err != nil { + return nil, errors.WithStack(err) + } + + regScript := regexp.MustCompile(`(?im)\