Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Video not playing on device (IOS) #33

Open
mbacarro opened this issue Jul 10, 2024 · 5 comments
Open

Video not playing on device (IOS) #33

mbacarro opened this issue Jul 10, 2024 · 5 comments

Comments

@mbacarro
Copy link

Got to the video portion at around the 3 hour mark and fonud that the videos weren't loading. I added the onError property to the

The server is not correctly configured. - The AVPlayerItem instance has failed with the error code -11850 and domain "AVFoundationErrorDomain"

Here's the code I have related to this error

import { ResizeMode, Video } from "expo-av";
.
.
.
                <Video
                    source={{ uri: item.video}}
                    className="w-52 h-72 rounded-[33px] mt-3 bg-white/10"
                    resizeMode={ResizeMode.CONTAIN}
                    useNativeControls
                    shouldPlay
                    onPlaybackStatusUpdate={(status) => {
                    if (status.didJustFinish) {
                        setPlay(false);
                    }
                    }}
                    onError={(error) => {
                        console.error("Video error: ", error); // Log the error
                    }}
                />

I think it's my device but not sure how to fix it

@RazvanBalota
Copy link

Hi there,

I have the same problem. I don't have a solution for you but it seems like the url videos are broken? I mean i can play them in my browser but for some reasons they are not playing on my device (iPhone 13 Pro Max running ios 18 beta 3), but if I use another url for the videos they work.

@mbacarro
Copy link
Author

Weird, for me its any URL, it only works if I download a video and put the file path name as the source.

@Mik3ll
Copy link

Mik3ll commented Jul 25, 2024

https://docs.expo.dev/versions/latest/sdk/video-av/

The format of the url should contain the .mp4. Something like this https://yourserver.com/path/to/video.mp4
Vimeo or Youtube doesn't support it, if you want to use it from Vimeo, you need to use their API

@Jeremydfrancis
Copy link

Jeremydfrancis commented Aug 21, 2024

You can also use react-native-webview if you prefer to use something other than the API route for embedded videos. This allows you to easily use embed videos from platforms like YouTube and Vimeo directly within your React Native application. I implemented logic to detect whether the video URL is a direct or embedded link. Depending on the result, the component renders the Video component (for direct links) or a WebView (for embedded videos).

Additionally, you'll need to apply similar changes to your app's VideoCard component to handle embedded videos correctly.

  • Make sure to install react-native-webview in your terminal. Below is an example of how I implemented this in my Trending component:
import { ResizeMode, Video } from "expo-av";
import * as Animatable from "react-native-animatable";
import {
  FlatList,
  Image,
  ImageBackground,
  TouchableOpacity,
  View,
  Dimensions,
} from "react-native";
import { WebView } from "react-native-webview";

import { icons } from "../constants";

const zoomIn = {
  0: {
    scale: 0.9,
  },
  1: {
    scale: 1,
  },
};

const zoomOut = {
  0: {
    scale: 1,
  },
  1: {
    scale: 0.9,
  },
};

const isEmbeddedVideo = (url) => {
  return url.includes("youtube.com") || url.includes("vimeo.com");
};

const TrendingItem = ({ activeItem, item }) => {
  const [play, setPlay] = useState(false);
  const isEmbedded = isEmbeddedVideo(item.video);

  const itemStyle = {
    width: Dimensions.get("window").width * 0.55,
    height: Dimensions.get("window").height * 0.45,
    borderRadius: 33,
    overflow: "hidden",
    marginTop: 15,
    backgroundColor: "rgba(255, 255, 255, 0.1)",
  };

  return (
    <Animatable.View
      style={{ marginRight: 20 }}
      animation={activeItem === item.$id ? zoomIn : zoomOut}
      duration={500}
    >
      {play ? (
        isEmbedded ? (
          <View style={itemStyle}>
            <WebView
              source={{ uri: item.video }}
              style={{ flex: 1 }}
              allowsInlineMediaPlayback={true}
              javaScriptEnabled={true}
              allowsFullscreenVideo={true}
              scalesPageToFit={true}
              startInLoadingState={true}
            />
          </View>
        ) : (
          <View style={itemStyle}>
            <Video
              source={{ uri: item.video }}
              style={{ flex: 1 }}
              useNativeControls
              resizeMode={ResizeMode.COVER}
              shouldPlay
              onPlaybackStatusUpdate={(status) => {
                if (status.didJustFinish) {
                  setPlay(false);
                }
              }}
              onError={(error) => {
                console.error("Video error:", error);
                setPlay(false);
              }}
            />
          </View>
        )
      ) : (
        <TouchableOpacity
          style={itemStyle}
          activeOpacity={0.7}
          onPress={() => setPlay(true)}
        >
          <ImageBackground
            source={{ uri: item.thumbnail }}
            style={{ width: "100%", height: "100%" }}
            resizeMode="cover"
          >
            <View
              style={{
                justifyContent: "center",
                alignItems: "center",
                flex: 1,
              }}
            >
              <Image
                source={icons.play}
                style={{ width: 48, height: 48 }}
                resizeMode="contain"
              />
            </View>
          </ImageBackground>
        </TouchableOpacity>
      )}
    </Animatable.View>
  );
};

const Trending = ({ posts }) => {
  const [activeItem, setActiveItem] = useState(posts[0]);

  const viewableItemsChanged = ({ viewableItems }) => {
    if (viewableItems.length > 0) {
      setActiveItem(viewableItems[0].key);
    }
  };

  return (
    <FlatList
      data={posts}
      horizontal
      keyExtractor={(item) => item.$id}
      renderItem={({ item }) => (
        <TrendingItem activeItem={activeItem} item={item} />
      )}
      onViewableItemsChanged={viewableItemsChanged}
      viewabilityConfig={{
        itemVisiblePercentThreshold: 70,
      }}
      contentOffset={{ x: 170 }}
    />
  );
};

export default Trending; 


@Mullermtg
Copy link

Fixed the issue for me.

I has two issues.

  1. Video only allowing .mp4 files to play.
  2. className styling not applying to

I changed the sample URLs in appWrite to:
http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4
http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4
http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4

And wrapped the video component:
const StyledVideo = ({ className, ...props } => (

<Video style={{ width: '100%', height: '100%' }} {...props} />

)

Anyone knows a cleaner way to get third party components to work with NativeWind? Or is this a config issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants