diff --git a/app.json b/app.json
index c930458a7a7a4c98a26c08f93a60de55ca561be3..af7c947ebf7db5c20672dee86e8922622985be5a 100644
--- a/app.json
+++ b/app.json
@@ -13,13 +13,15 @@
       "backgroundColor": "#ffffff"
     },
     "ios": {
-      "supportsTablet": true
+      "supportsTablet": true,
+      "bundleIdentifier": "com.lykomonix.vili"
     },
     "android": {
       "adaptiveIcon": {
         "foregroundImage": "./assets/adaptive-icon.png",
         "backgroundColor": "#ffffff"
-      }
+      },
+      "package": "com.lykomonix.vili"
     },
     "web": {
       "favicon": "./assets/favicon.png"
diff --git a/components/buttons/AnswerButton.tsx b/components/buttons/AnswerButton.tsx
index 5b861da586b2e3dc37366d3ea982c9ac136b67ba..fb4c08a5a3a08db741b9b7847d38ab28c38f81cb 100644
--- a/components/buttons/AnswerButton.tsx
+++ b/components/buttons/AnswerButton.tsx
@@ -2,6 +2,8 @@ import {TouchableOpacity, Text, StyleSheet, View, Image} from "react-native";
 import {ButtonsStyles} from "../../styles/ButtonsStyles";
 import {TextsStyles} from "../../styles/TextsStyles";
 import React from "react";
+import Base64AudioPlayer from "./Base64AudioPlayer";
+
 
 interface Props{
     text: string;
@@ -9,6 +11,7 @@ interface Props{
     buttonStyle?: any;
     buttonText?: any;
     indicator?: number | undefined;
+    forceEnd: boolean;
 }
 
 /**
@@ -18,7 +21,7 @@ interface Props{
  * @param buttonStyle - Surcharge du style du bouton
  * @param buttonText - Surcharge du style du texte du bouton
  */
-export default function AnswerButton({text, handleButtonPressed, buttonStyle, buttonText, indicator}: Props){
+export default function AnswerButton({text, handleButtonPressed, buttonStyle, buttonText, indicator, forceEnd}: Props){
     return(
         <View style={styles.containerButton}>
             <TouchableOpacity onPress={handleButtonPressed} style={[styles.defaultButton,buttonStyle]}>
@@ -35,9 +38,9 @@ export default function AnswerButton({text, handleButtonPressed, buttonStyle, bu
                     />
                 :
                     text.includes('data:audio') ?
-                    <Text style={[TextsStyles.defaultButtonText, buttonText]}>sound: not supported</Text>
+                        <Base64AudioPlayer base64Audio={text} forceEnd={forceEnd}/>
                     :
-                    <Text style={[TextsStyles.defaultButtonText, buttonText]}>{text}</Text>
+                        <Text style={[TextsStyles.defaultButtonText, buttonText]}>{text}</Text>
                 }
             </TouchableOpacity>
         </View>
diff --git a/components/buttons/AnswerButtonImage.tsx b/components/buttons/AnswerButtonImage.tsx
deleted file mode 100644
index 8716144bd818a697248cf67eddd8e6a29e1b0cb3..0000000000000000000000000000000000000000
--- a/components/buttons/AnswerButtonImage.tsx
+++ /dev/null
@@ -1,73 +0,0 @@
-import {TouchableOpacity, Text, StyleSheet, View, Image} from "react-native";
-import {ButtonsStyles} from "../../styles/ButtonsStyles";
-import {TextsStyles} from "../../styles/TextsStyles";
-
-interface Props{
-    url: string;
-    handleButtonPressed:() => void;
-    buttonStyle?: any;
-    indicator?: number | undefined;
-}
-
-/**
- * AnswerButtonImage : Un bouton par défaut, il possède déjà un style mais on peut le surcharger grâce à la propriété buttonStyle
- * @param url - Texte du bouton
- * @param handleButtonPressed - Fonction qui sera exécutée lorsque le bouton sera pressé
- * @param buttonStyle - Surcharge du style du bouton
- * @param buttonText - Surcharge du style du texte du bouton
- */
-export default function AnswerButtonImage({url, handleButtonPressed, buttonStyle, indicator}: Props){
-    return(
-        <View style={styles.containerButton}>
-            <TouchableOpacity onPress={handleButtonPressed} style={[styles.defaultButton,buttonStyle]}>
-                {indicator !== undefined && (
-                    <View style={styles.indicator}>
-                        <Text style={styles.indicatorText}>{indicator}</Text>
-                    </View>
-                )}
-                <Image 
-                    style={[styles.answerImage]}
-                    source={{uri: url}}
-                />
-            </TouchableOpacity>
-        </View>
-    )
-}
-
-const styles = StyleSheet.create({
-    defaultButton: {
-        backgroundColor: "#45128C",
-        padding: 10,
-        alignItems: "center",
-        justifyContent: 'center',
-        borderRadius: 10,
-    },
-    indicator: {
-        position: "absolute",
-        top: "-16%",
-        left: "5%",
-        width: 25,
-        height: 25,
-        borderRadius: 15,
-        backgroundColor: "#D3D3D3",
-        justifyContent: "center",
-        alignItems: "center",
-        zIndex: 1,
-    },
-    indicatorText: {
-        color: "#000",
-        fontWeight: "bold",
-        fontSize: 14,
-    },
-    answerImage: {
-        width: '100%',
-        height: '100%',
-    },
-    containerButton: {
-        height: 150, 
-        width: '100%',
-        display: 'flex',
-        alignItems: 'center',
-        justifyContent: 'center'
-    }
-})
\ No newline at end of file
diff --git a/components/buttons/Base64AudioPlayer.tsx b/components/buttons/Base64AudioPlayer.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..ba0e71b59b3b257456ff098439af3bc871a28f55
--- /dev/null
+++ b/components/buttons/Base64AudioPlayer.tsx
@@ -0,0 +1,51 @@
+import React, { useEffect, useState } from 'react';
+import { View, Button, Text } from 'react-native';
+import { Audio } from 'expo-av';
+
+interface Props {
+  base64Audio: string;
+  forceEnd: boolean;
+}
+
+export default function Base64AudioPlayer({ base64Audio, forceEnd }: Props) {
+  const [sound, setSound] = useState<Audio.Sound | null>(null);
+  const [isPlaying, setIsPlaying] = useState(false);
+
+  const playAudio = async () => {
+    try {
+      const { sound } = await Audio.Sound.createAsync(
+        { uri: `${base64Audio}` }
+      );
+      setSound(sound);
+
+      await sound.playAsync();
+      setIsPlaying(true);
+
+      sound.setOnPlaybackStatusUpdate((status) => {
+        if (status.isLoaded && !status.isBuffering && status.didJustFinish) {
+          setIsPlaying(false);
+        }
+      });
+    } catch (error) {
+      console.error('Erreur lors de la lecture de l\'audio :', error);
+    }
+  };
+
+  const stopAudio = async () => {
+    if (sound) {
+      await sound.stopAsync();
+      setIsPlaying(false);
+    }
+  };
+
+  useEffect(() => {
+    stopAudio();
+  }, [forceEnd]);
+  
+  return (
+    <View style={{ padding: 20 }}>
+      <Text style={{ marginBottom: 10 }}>Appuyer pour jouer l'audio</Text>
+      <Button title={isPlaying ? 'Arrêter l\'audio' : 'Jouer l\'audio'} onPress={isPlaying ? stopAudio : playAudio} />
+    </View>
+  );
+}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 2a605a2226b077d10f3560a61b36c7d1b97e4f1d..1fa047132afbd03c21c6db817cfcd93f67234e50 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -19,6 +19,7 @@
         "axios": "^1.7.9",
         "dotenv": "^16.4.7",
         "expo": "~52.0.14",
+        "expo-av": "~15.0.2",
         "expo-splash-screen": "^0.29.13",
         "expo-status-bar": "~2.0.0",
         "he": "^1.2.0",
@@ -28,9 +29,11 @@
         "react-i18next": "^15.1.1",
         "react-native": "0.76.3",
         "react-native-dropdown-select-list": "^2.0.5",
+        "react-native-fs": "^2.20.0",
         "react-native-progress": "^5.0.1",
         "react-native-safe-area-context": "^4.12.0",
         "react-native-screens": "~4.1.0",
+        "react-native-sound": "^0.11.2",
         "react-native-sse": "^1.2.1",
         "react-native-vector-icons": "^10.2.0",
         "react-query": "^3.39.3",
@@ -4662,6 +4665,11 @@
       "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
       "license": "MIT"
     },
+    "node_modules/base-64": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz",
+      "integrity": "sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA=="
+    },
     "node_modules/base64-js": {
       "version": "1.5.1",
       "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
@@ -6126,6 +6134,23 @@
         "react-native": "*"
       }
     },
+    "node_modules/expo-av": {
+      "version": "15.0.2",
+      "resolved": "https://registry.npmjs.org/expo-av/-/expo-av-15.0.2.tgz",
+      "integrity": "sha512-AHIHXdqLgK1dfHZF0JzX3YSVySGMrWn9QtPzaVjw54FAzvXfMt4sIoq4qRL/9XWCP9+ICcCs/u3EcvmxQjrfcA==",
+      "license": "MIT",
+      "peerDependencies": {
+        "expo": "*",
+        "react": "*",
+        "react-native": "*",
+        "react-native-web": "*"
+      },
+      "peerDependenciesMeta": {
+        "react-native-web": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/expo-constants": {
       "version": "17.0.3",
       "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-17.0.3.tgz",
@@ -9740,6 +9765,25 @@
       "integrity": "sha512-TepbcagQVUMB6nLuIlVU2ghRpQHAECOeZWe8K04ymW6NqbKbxuczZSDFfdCiABiiQ2dFD+8Dz65y4K7/uUEqGg==",
       "license": "MIT"
     },
+    "node_modules/react-native-fs": {
+      "version": "2.20.0",
+      "resolved": "https://registry.npmjs.org/react-native-fs/-/react-native-fs-2.20.0.tgz",
+      "integrity": "sha512-VkTBzs7fIDUiy/XajOSNk0XazFE9l+QlMAce7lGuebZcag5CnjszB+u4BdqzwaQOdcYb5wsJIsqq4kxInIRpJQ==",
+      "license": "MIT",
+      "dependencies": {
+        "base-64": "^0.1.0",
+        "utf8": "^3.0.0"
+      },
+      "peerDependencies": {
+        "react-native": "*",
+        "react-native-windows": "*"
+      },
+      "peerDependenciesMeta": {
+        "react-native-windows": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/react-native-progress": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/react-native-progress/-/react-native-progress-5.0.1.tgz",
@@ -9776,6 +9820,15 @@
         "react-native": "*"
       }
     },
+    "node_modules/react-native-sound": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npmjs.org/react-native-sound/-/react-native-sound-0.11.2.tgz",
+      "integrity": "sha512-LmGc8lgOK3qecYMVQpyHvww/C+wgT6sWeMpVbOe4NCRGC2yKd4fo4U0KBUo9PO7AqKESO3I/2GZg1/C0+bwiiA==",
+      "license": "MIT",
+      "peerDependencies": {
+        "react-native": ">=0.8.0"
+      }
+    },
     "node_modules/react-native-sse": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/react-native-sse/-/react-native-sse-1.2.1.tgz",
@@ -11563,6 +11616,12 @@
         "react": ">=16.8"
       }
     },
+    "node_modules/utf8": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz",
+      "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==",
+      "license": "MIT"
+    },
     "node_modules/util-deprecate": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
diff --git a/package.json b/package.json
index fd3a2bf9088f4150929498d11e1f5854e6b360de..26120e57f9d044773e714c74bb5e4099ee821076 100644
--- a/package.json
+++ b/package.json
@@ -36,7 +36,8 @@
     "react-native-vector-icons": "^10.2.0",
     "react-query": "^3.39.3",
     "rxjs": "^7.8.1",
-    "socket.io-client": "^4.8.1"
+    "socket.io-client": "^4.8.1",
+    "expo-av": "~15.0.2"
   },
   "devDependencies": {
     "@babel/core": "^7.20.0",
diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index 619e3b7c2e91e2879e7c388106b136af79b794c5..a8613184a7d93b4e483c65cf4b2ba722f4f29655 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -11,7 +11,6 @@ import {Answer} from "../../models/Answer";
 import {Quiz} from "../../models/Quiz";
 import AnswerButton from "../../components/buttons/AnswerButton";
 import {QuizInformations} from "../../models/QuizInformations";
-import AnswerButtonImage from "../../components/buttons/AnswerButtonImage";
 
 interface Props {
     quizInformations?: QuizInformations;
@@ -71,6 +70,7 @@ export default function PlayingQuizBody({ quizInformations, runId, actualQuestio
     const [quizState, setQuizState] = useState(QuizState.ANSWERING);
     const [correctAnswerId, setCorrectAnswerId] = useState<number | null>(null);
     const [isLastQuestion, setIsLastQuestion] = useState(false);
+    const [forceEnd, setForceEnd] = useState(false);
 
     const {answerQuestion} = useQuizService();
     const getCorrectAnswer = (answers: Answer[]): Answer => {
@@ -81,6 +81,7 @@ export default function PlayingQuizBody({ quizInformations, runId, actualQuestio
     const onValidation = async () => {
         if(selectedAnswerId === null) return;
         setQuizState(QuizState.LOADING);
+        setForceEnd(!forceEnd);
         const answerId = actualQuestion.answers.find((answer) => answer.id === selectedAnswerId)?.id;
         if(!answerId || !runId) return;
         const answereFetched = await answerQuestion(runId, actualQuestion.id, answerId);
@@ -101,7 +102,8 @@ export default function PlayingQuizBody({ quizInformations, runId, actualQuestio
         }
 
     };
-    const onContinue = () => {
+    const onContinue = async () => {
+        await setForceEnd(!forceEnd);
         if(isLastQuestion) {
             navigation.reset({
                 index: 0,
@@ -136,23 +138,15 @@ export default function PlayingQuizBody({ quizInformations, runId, actualQuestio
                         contentContainerStyle={styles.buttonListContentContainer}
                     >
                         {actualQuestion.answers.map((answer, index) => (
-                            actualQuestion.type === "image" ? 
-                                <AnswerButtonImage
-                                    key={index}
-                                    url={answer.text}
-                                    handleButtonPressed={() => onAnsweredButtonClicked(answer.id)}
-                                    buttonStyle={getStyleOfAnswerButton(answer.id, selectedAnswerId, correctAnswerId, quizState)}
-                                />
-                            :
-                                <AnswerButton
-                                    key={index}
-                                    text={answer.text}
-                                    handleButtonPressed={() => onAnsweredButtonClicked(answer.id)}
-                                    buttonStyle={getStyleOfAnswerButton(answer.id, selectedAnswerId, correctAnswerId, quizState)}
-                                    buttonText={getStyleOfAnswerButtonText(answer.id, selectedAnswerId, correctAnswerId, quizState)}
-                                />
+                            <AnswerButton
+                                key={index}
+                                text={answer.text}
+                                handleButtonPressed={() => onAnsweredButtonClicked(answer.id)}
+                                buttonStyle={getStyleOfAnswerButton(answer.id, selectedAnswerId, correctAnswerId, quizState)}
+                                buttonText={getStyleOfAnswerButtonText(answer.id, selectedAnswerId, correctAnswerId, quizState)}
+                                forceEnd={forceEnd}
+                            />
                         ))}
-                        {/* </View> */}
                     </ScrollView>
                     <View style={styles.playButtonContainer}>
                         <BlueButton onPress={() => quizState === QuizState.ANSWERING ? onValidation() : onContinue()} text={quizState === QuizState.ANSWERING ? "CONFIRM" : "CONTINUE"} buttonStyle={{borderRadius: 50}} isDisabled={false}/>