tubefetcherlib 0.1.1
A modular and extensible Python library to fetch video stream URLs and metadata from various platforms.
Requires Python: >=3.8
Keywords: youtube, instagram, video, stream, metadata, fetcher

# TubeFetcherLib

![Python Version](https://img.shields.io/badge/python-3.8%2B-blue.svg)
![License](https://img.shields.io/badge/license-MIT-green.svg)
[![PyPI version](https://badge.fury.io/py/tubefetcherlib.svg)](https://badge.fury.io/py/tubefetcherlib)

A `TubeFetcherLib` é uma biblioteca Python modular e extensível projetada para extrair URLs de stream de vídeo e metadados de várias plataformas, começando com YouTube e Instagram. O objetivo é fornecer uma interface unificada para acessar informações de vídeo de diferentes provedores, permitindo fácil expansão para novas fontes no futuro.

## Funcionalidades

*   **Extração de URL de Stream:** Obtenha a URL direta do stream de vídeo para diferentes qualidades (quando disponível).
*   **Extração de Metadados:** Recupere informações detalhadas sobre o vídeo, como título, autor, duração, visualizações e URL da thumbnail.
*   **Suporte a Múltiplos Provedores:** Atualmente suporta YouTube e Instagram.
*   **Design Extensível:** Facilmente adiciona novos provedores de vídeo através de uma arquitetura baseada em Strategy Pattern.
*   **Configuração Flexível:** Gerenciamento centralizado de configurações como timeouts, retries e proxies.
*   **Tratamento de Erros Robusto:** Exceções personalizadas para diferentes cenários de falha.
*   **Logging Integrado:** Utiliza o módulo `logging` do Python para mensagens informativas e de depuração.

## Instalação

Você pode instalar `TubeFetcherLib` via pip:

```bash
pip install tubefetcherlib
```

## Uso

### Extraindo URL de Stream e Informações do Vídeo

A biblioteca oferece três funções principais para interagir com os provedores de vídeo: `get_video_stream_url`, `get_video_info` e `get_available_qualities`.

#### `get_video_stream_url(video_url: str, quality: StreamQuality = StreamQuality.HIGHEST, instagram_username: str = None, instagram_password: str = None, config: Optional[Config] = None) -> str`
Retorna a URL direta do stream de vídeo para a qualidade especificada.

*   `video_url` (str): A URL do vídeo (YouTube, Instagram, etc.).
*   `quality` (StreamQuality, opcional): A qualidade desejada do stream. Padrão para `StreamQuality.HIGHEST`.
*   `instagram_username` (str, opcional): Nome de usuário do Instagram para autenticação (necessário para conteúdo privado ou para evitar limitações de taxa).
*   `instagram_password` (str, opcional): Senha do Instagram para autenticação.
*   `config` (Config, opcional): Uma instância da classe `Config` para configurações personalizadas.

#### `get_video_info(video_url: str, instagram_username: str = None, instagram_password: str = None, config: Optional[Config] = None) -> Dict[str, Any]`
Retorna um dicionário contendo metadados detalhados do vídeo.

*   `video_url` (str): A URL do vídeo.
*   `instagram_username` (str, opcional): Nome de usuário do Instagram.
*   `instagram_password` (str, opcional): Senha do Instagram.
*   `config` (Config, opcional): Uma instância da classe `Config` para configurações personalizadas.

O dicionário retornado pode incluir chaves como `'title'`, `'author'`, `'duration'`, `'views'`, `'thumbnail_url'`, etc., dependendo do provedor.

#### `get_available_qualities(video_url: str, instagram_username: str = None, instagram_password: str = None, config: Optional[Config] = None) -> List[StreamQuality]`
Retorna uma lista de objetos `StreamQuality` que representam as qualidades de stream disponíveis para o vídeo.

*   `video_url` (str): A URL do vídeo.
*   `instagram_username` (str, opcional): Nome de usuário do Instagram.
*   `instagram_password` (str, opcional): Senha do Instagram.
*   `config` (Config, opcional): Uma instância da classe `Config` para configurações personalizadas.

### Enum `StreamQuality`

Define as qualidades de stream de vídeo disponíveis.

*   `HIGHEST`: A mais alta qualidade disponível.
*   `LOWEST`: A mais baixa qualidade disponível.
*   `P1080`: 1080p (Full HD).
*   `P720`: 720p (HD).
*   `P480`: 480p (SD).
*   `P360`: 360p (SD).
*   `P240`: 240p (SD).
*   `P144`: 144p (SD).

**Nota sobre o Instagram:** O Instagram geralmente oferece apenas uma qualidade de stream, que será mapeada para `StreamQuality.HIGHEST`. Solicitar outras qualidades pode resultar em `UnsupportedQualityError`.

### Classe `Config`

Permite configurar o comportamento da biblioteca, como timeouts, retries e proxies.

*   `instagram_session_dir` (str): Diretório onde o Instaloader (usado para Instagram) salvará/carregará os arquivos de sessão. Padrão: `.` (diretório atual).
*   `timeout` (int): Tempo limite em segundos para requisições de rede. Padrão: `30`.
*   `proxies` (Optional[Dict[str, str]]): Um dicionário de proxies para requisições HTTP/HTTPS. Ex: `{'http': 'http://user:pass@host:port', 'https': 'https://user:pass@host:port'}`. Padrão: `None`.
*   `retries` (int): Número de tentativas para requisições de rede falhas. Padrão: `3`.
*   `backoff_factor` (float): Fator para o backoff exponencial entre as tentativas. Padrão: `0.5`.

### Exemplos de Uso

```python
from tubefetcherlib.main import get_video_stream_url, get_video_info, get_available_qualities
from tubefetcherlib.providers.base import StreamQuality
from tubefetcherlib.config import Config
from tubefetcherlib.exceptions import VideoNotFoundError, InvalidURLError, StreamUnavailableError, UnsupportedQualityError, ProviderAuthenticationError

# Exemplo de uso com YouTube
youtube_url = "https://www.youtube.com/watch?v=LXb3EKWsInQ" # Exemplo de vídeo de domínio público

try:
    # Obter a URL do stream na qualidade mais alta
    stream_url_highest = get_video_stream_url(youtube_url, quality=StreamQuality.HIGHEST)
    print(f"YouTube Stream URL (Highest): {stream_url_highest}")

    # Obter a URL do stream em 720p
    stream_url_720p = get_video_stream_url(youtube_url, quality=StreamQuality.P720)
    print(f"YouTube Stream URL (720p): {stream_url_720p}")

    # Obter informações do vídeo
    video_info = get_video_info(youtube_url)
    print(f"YouTube Video Info: {video_info['title']} by {video_info['author']}")

    # Obter qualidades disponíveis
    available_qualities = get_available_qualities(youtube_url)
    print(f"YouTube Available Qualities: {[q.value for q in available_qualities]}")

except (VideoNotFoundError, InvalidURLError, StreamUnavailableError, UnsupportedQualityError) as e:
    print(f"Erro específico do YouTube: {e}")
except Exception as e:
    print(f"Erro inesperado ao processar vídeo do YouTube: {e}")

print("-" * 30)

# Exemplo de uso com Instagram (para conteúdo público)
# Note: O Instagram pode ter restrições de acesso sem autenticação.
instagram_url = "https://www.instagram.com/p/C71_y_1o_1o/" # Substitua por uma URL de vídeo real

try:
    # Obter a URL do stream (Instagram geralmente oferece apenas uma qualidade)
    stream_url_ig = get_video_stream_url(instagram_url)
    print(f"Instagram Stream URL: {stream_url_ig}")

    # Obter informações do vídeo
    video_info_ig = get_video_info(instagram_url)
    print(f"Instagram Video Info: {video_info_ig['title']} by {video_info_ig['author']}")

    # Obter qualidades disponíveis (Instagram geralmente retorna apenas HIGHEST)
    available_qualities_ig = get_available_qualities(instagram_url)
    print(f"Instagram Available Qualities: {[q.value for q in available_qualities_ig]}")

except (VideoNotFoundError, InvalidURLError, StreamUnavailableError, UnsupportedQualityError) as e:
    print(f"Erro específico do Instagram: {e}")
except Exception as e:
    print(f"Erro inesperado ao processar vídeo do Instagram: {e}")

print("-" * 30)

# Exemplo de uso com configurações personalizadas (para Instagram com credenciais)
# É ALTAMENTE RECOMENDADO usar variáveis de ambiente ou um gerenciador de segredos
# para credenciais em ambientes de produção.
# Ex: export INSTAGRAM_USERNAME="seu_usuario"
#     export INSTAGRAM_PASSWORD="sua_senha"

import os

my_username = os.environ.get("INSTAGRAM_USERNAME")
my_password = os.environ.get("INSTAGRAM_PASSWORD")

if my_username and my_password:
    custom_config = Config(
        instagram_session_dir="./sessions", # Onde salvar/carregar a sessão do Instaloader
        timeout=90,
        retries=10,
        proxies={"http": "http://your.proxy.com:8080", "https": "https://your.proxy.com:8080"}
    )
    
    try:
        print("Tentando acessar Instagram com credenciais...")
        stream_url_ig_auth = get_video_stream_url(
            instagram_url,
            instagram_username=my_username,
            instagram_password=my_password,
            config=custom_config
        )
        print(f"Instagram Stream URL (Authenticated): {stream_url_ig_auth}")
    except ProviderAuthenticationError as e:
        print(f"Erro de autenticação do Instagram: {e}")
    except Exception as e:
        print(f"Erro inesperado ao processar vídeo do Instagram com credenciais: {e}")
else:
    print("Variáveis de ambiente INSTAGRAM_USERNAME e INSTAGRAM_PASSWORD não definidas. Pulando teste de autenticação do Instagram.")

```

### Tratamento de Erros

A biblioteca levanta exceções personalizadas para diferentes cenários de erro. É fundamental envolver as chamadas da biblioteca em blocos `try-except` para lidar com esses erros de forma robusta.

*   `VideoFetcherError`: Classe base para todas as exceções da biblioteca.
*   `VideoNotFoundError`: O vídeo não foi encontrado ou está indisponível.
*   `ProviderAuthenticationError`: Problemas de autenticação com o provedor (ex: credenciais inválidas para Instagram).
*   `StreamUnavailableError`: O stream solicitado não está disponível (ex: vídeo removido, restrição geográfica).
*   `UnsupportedQualityError`: A qualidade de stream solicitada não é suportada pelo provedor para o vídeo em questão.
*   `InvalidURLError`: A URL fornecida é inválida ou não pode ser processada por nenhum provedor conhecido.

```python
from tubefetcherlib.exceptions import VideoNotFoundError, InvalidURLError, ProviderAuthenticationError

try:
    # ... seu código de uso da biblioteca ...
    pass
except VideoNotFoundError as e:
    print(f"O vídeo não foi encontrado: {e}")
except InvalidURLError as e:
    print(f"A URL fornecida é inválida: {e}")
except ProviderAuthenticationError as e:
    print(f"Falha na autenticação com o provedor: {e}")
except Exception as e:
    print(f"Ocorreu um erro inesperado: {e}")
```

## Configuração para Desenvolvimento

Para configurar o ambiente de desenvolvimento e contribuir para a `TubeFetcherLib`, siga os passos abaixo:

1.  **Clone o repositório:**
    ```bash
    git clone https://github.com/heyjunin/tubefetcherlib.git
    cd tubefetcherlib
    ```

2.  **Crie e ative um ambiente virtual:**
    É altamente recomendado usar um ambiente virtual para isolar as dependências do projeto.
    ```bash
    python3 -m venv .venv
    source .venv/bin/activate
    ```

3.  **Instale as dependências de desenvolvimento:**
    ```bash
    pip install -e .
    pip install pytest
    ```
    O comando `pip install -e .` instala a biblioteca em modo "editável", o que significa que as alterações no código-fonte serão refletidas sem a necessidade de reinstalar.

4.  **Execute os testes:**
    Para garantir que suas alterações não introduziram regressões, execute os testes:
    ```bash
    pytest
    ```

## Contribuição

Contribuições são bem-vindas! Se você deseja contribuir para o `TubeFetcherLib`, por favor, siga estas diretrizes:

1.  Faça um fork do repositório.
2.  Crie uma nova branch para sua feature (`git checkout -b feature/AmazingFeature`).
3.  Faça suas alterações e certifique-se de que os testes passem.
4.  Commite suas alterações (`git commit -m 'Add some AmazingFeature'`).
5.  Envie para a branch (`git push origin feature/AmazingFeature`).
6.  Abra um Pull Request.

## Licença

Este projeto está licenciado sob a Licença MIT - veja o arquivo [LICENSE](LICENSE) para detalhes.

## Contato

Para dúvidas ou suporte, por favor, abra uma issue no repositório do GitHub.

**Desenvolvido por:** heyjunin